Reputation: 1
I am currently working on an old codebase for a Delphi server application, in which I'm trying to fix a memory leak that causes the server to crash due to out of memory. The allocations are about 1MB in size and occur exactly every 5 seconds. I'm working on RAD Studio 10.2, and the code is written in Delphi 10.2.
The only information I was provided with was that the application was migrated from Oracle 11 to Oracle 12 recently, alongside some changes in the code. Since there was no version control before I arrived, I cannot pinpoint the exact change that introduced the leak.
Tools like Deleaker, FastMM or Memory Validator all fail to pinpoint the exact allocation that causes the problem. The issue seems to be in the code which communicates with the database, since Memory Validator reports leaks in oraciei12.dll
, but even after fixing some deprecation warnings in the code, it still isn't fixed. These tools are also limited by the unavailability of debug symbols in some DLLs and some parts of the compiled executable.
I am familiar with Valgrind from previous experience with C/C++, however the code cannot be compiled on Linux due to the use of Win32 procedures and calls to VCL functions.
I also tried using delphi-leakcheck
, SamplingProfiler
, and gpprofile2017
, which all failed due to different causes (multithreading not supported, does not catch certain allocations, etc.).
EDIT: the code already runs with madExcept and ReportMemoryLeaksOnShutdown
is set. However, no leaks are reported... maybe that memory is still reachable somehow ? Or it is allocated by a different thread and cannot be detected by madExcept ? Also, FastMMUsageTracker fails due to multithreading, and VMMap does not show the exact details of where memory was allocated.
The code references CodeSite through preprocessor directives, but the version of CodeSite bundled with RAD Studio does not track memory usage.
Are there any other methods for determining the root cause of this leak ?
Upvotes: 0
Views: 200
Reputation: 43023
You may try to switch from the OCI client you are using to another one, to see it the leaks comes from the Delphi OCI client library, which may not release a resource.
My advice would be to try to reduce the scope of your problem by creating a minimal project which reproduces the issue. For instance, access the database and run a statement which trigger leaks. Then narrow it down by commenting some function calls, going into nested calls, until you identify the culprit.
If it comes from a background thread (running every 5 seconds?), then you could check the Execute
method of this thread, and how it initializes the OCI layer. Perhaps the Oracle client library needs some specific thread initialization or finalization (e.g. statement cache) which is not properly done in the short-living sub-thread.
Upvotes: 2