Browse Prior Art Database

Method for identifying native memory leaks in a managed runtime

IP.com Disclosure Number: IPCOM000176278D
Original Publication Date: 2008-Nov-11
Included in the Prior Art Database: 2008-Nov-11
Document File: 2 page(s) / 47K

Publishing Venue

IBM

Abstract

Disclosed is a method for analysing native (operating system process, rather than managed) memory leaks in a process running a managed runtime such as Java*. It works by cross-referencing native memory segments (as recorded in C library malloc tables) with the fields of managed objects that are typically used to hold native pointers when mixing native code with a managed runtime application. A more accurate extension based on static analysis of the application code is also disclosed.

This text was extracted from a PDF file.
This is the abbreviated version, containing approximately 49% of the total text.

Page 1 of 2

Method for identifying native memory leaks in a managed runtime

A managed runtime (such as a Java* runtime environment) provides a virtual environment to execute a program with a managed memory architecture (one that is controlled by a garbage collector). During execution, when a program allocates an object, that allocation is satisfied on the managed heap.

    Managed runtimes can also allow native (unmanaged code) to be run as part of the managed program. In the Java environment this ability is called the Java Native Interface (JNI) and allows object methods to be implemented in native languages such as C, C++, Fortran and Ada. Although the native code can allocate managed heap memory, it can also allocate native (unmanaged) memory through the OS memory operations such as malloc, new and LocalAlloc.

    The native memory used by the native components of a program is allocated from the same address space as the managed runtime itself - which is constrained by the architecture of the underlying operating system and hardware. Excessive native allocation can lead to native heap exhaustion - which can cause the managed runtime to malfunction.

    Native memory growth in a managed runtime environment can be debugged like any other native process in one of 3 ways:

Logic can be added to every memory operation to print a message when native memory is allocated or freed and where the operation was called from. The trace can be post-processed to identify call-sites that are allocating memory without it being freed (leaking memory). This causes a significant runtime performance overhead - and so is seldom enabled by default.

Logic can be added to every memory operation to summarise memory behaviour in memory - for each call site a running total of allocated bytes vs. freed bytes is maintained that can be used to identify any that are leaking memory. This causes a runtime performance impact and also increases memory use (to store the summary data) - and so is seldom enabled by default.

Logic can be added to the allocation routines to pad each allocated region of memory with a buffer that describes where the region was allocated from. If a core dump is taken, allocated memory can be identified and the call sites analysed. This has a runtime performance overhead and increases the memory footprint of the application - and is also seldom enabled by default.

    All of these approaches have runtime performance and memory footprint impacts.

    Managed applications with native components typically allocate a region of memory for each managed object (to be used by the native routines associated by that object) that is freed when the object is garbage-collected. A pointer to the native region of memory is usually stored in a field of the managed object itself. This means that a portion of the native memory footprint of such an application is controlled by the number of objects of a particular class that are live.

    Garbage collect...