How to find which process is leaking file handles in Linux?
Probably the root cause is a bug in NFSv4 implementation: https://stackoverflow.com/a/5205459/280758
They have similar symptoms.
How OS handles memory leaks
Recommended reading : Operating Systems: Three Easy Pieces
On common OSes (e.g. Linux, Windows, MacOSX, Android) each process has its own virtual address space (and the heap memory, e.g. used for malloc
or mmap
, is inside that virtual address space), and when the process terminates, its entire virtual address space is destroyed.
So memory leaks don't survive the process itself.
There could be subtle corner cases (e.g. leaks on using shm_overview(7) or shmget(2)).
Read (for Linux) proc(5), try cat /proc/self/maps
, and see also this. Learn to use valgrind and the Address Sanitizer.
Read also about Garbage Collection. It is quite relevant.
How to check for memory leaks in a large scale c++ Linux application?
First of all...
and we reached the point when it is mandatory to make a roundup of checks for memory leaks.
This, actually, is a problem of methodology. Correctness should be the primary goal of any software piece and not an afterthought.
I will suppose though that you now realize this and how much easier it would have been to identify the problems had you been running an instrumented unit test at each commit.
So, what to do now ?
Runtime detection:
- Try to make Valgrind work, you probably have some environmental issues
- Try ASan, ThreadSan and MemSan; they are not trivial to setup under Linux but oh so impressive!
- Try instrumented builds: tcmalloc includes a heap-checker for example
- ...
Compile time detection:
- Turn on the warnings (preferably with
-Werror
) (not specific to your issue) - Use static analysis, such as Clang's, it may spot unpaired allocation routines
- ...
- Turn on the warnings (preferably with
Human detection:
- Code reviews: make sure all resources are allocated within RAII classes
- ...
Note: using only RAII classes helps removing memory leaks, but does not help with dangling references. Thankfully, detecting dangling references is what ASan does.
And once you have patched all the issues, make sure that this becomes part of the process. Changes should be reviewed and tested, always, so that rotten eggs are culled immediately rather than left to stink up the code base.
Windows memory metric to detect memory leak
GlobalMemoryStatusEx
is wrong. You do not want to fill up the machine memory until 5 GB are left in total.
You need GetProcessMemoryInfo
.
BOOL WINAPI GetProcessMemoryInfo(
__in HANDLE Process,
__out PPROCESS_MEMORY_COUNTERS ppsmemCounters,
__in DWORD cb
);
From an example using GetProcessMemoryInfo
:
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
void PrintMemoryInfo( DWORD processID )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Print information about the memory usage of the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return;
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
}
CloseHandle( hProcess );
}
int main( void )
{
// Get the list of process identifiers.
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
{
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the memory usage for each process
for ( i = 0; i < cProcesses; i++ )
{
PrintMemoryInfo( aProcesses[i] );
}
return 0;
}
Although unintuitive you need to read PagefileUsage
which gets you the committed memory which was allocated by your process. WorkingSetSize
is unreliable because if the machine gets tight on memory the OS will write all data to the page file. That can cause WorkingSetSize
to be small (e.g. 100 MB) but in reality you leaked already 20 GB of memory. This would result in a saw tooth pattern in memory consumption until the page file is full. Working set is only the actively used memory which might hide the multi GB memory leak if the machine is under memory pressure.
Related Topics
How to Change Port Number for Jenkins Installation in Ubuntu 12.04
Using the Universal Chess Interface
How to Grep Exact Literal String (No Regex)
How to Repeat a Dash (Hyphen) in Shell
How to Run Elasticsearch 2.1.1 as Root User in Linux MAChine
Auto Exit Telnet Command Back to Prompt Without Human Intervention ^] Quit Close Exit Code 1
Comparison of Integer and Floating Point Numbers in Shell Script
I Cannot Get a Result from a Single Line Put into the Erlang Shell
Linker Cannot Find Symbols, But Libraries Are Read and Symbols Exist
Which Perf Events Can Use Pebs
How to Read the Second-To-Last Line in a File Using Bash
Source Code of Pthread Library
The Meaning of Real, User, and Sys in Output of Linux Time Command
How Does Stat Command Calculate the Blocks of a File
Search Ms Word Files in a Directory for Specific Content in Linux
How to Make Sure the Floating Point Arithmetic Result the Same in Both Linux and Windows