1. Field of the Invention
The present invention generally relates to performing a memory leak analysis in a computing system. More particularly, the present invention relates to a method, system, computer program product, and computer program storage device for performing a memory leak analysis inside a virtual machine by utilizing a depth first search (DFS) algorithm.
2. Description of the Prior Art
A lot of computer programs suffer from memory leaks, where an amount of memory used by the programs increases over time due to a bug. In C language, a memory leak is created by losing a pointer to a section of memory. Java and other managed runtime environments (e.g., .NET) do not suffer from this class of memory leak (e.g., a memory leak caused by losing a pointer), as Java and other managed runtime environments use automatic garbage collection. However, in Java and .NET, it is still possible for a programmer to write a program that creates objects, uses them, then does not correctly make them available for garbage collection. For example, a memory leak pattern in Java or .NET is usually caused from a collection class with a large number of objects. In the memory leak pattern in Java or .NET, a programmer makes a mistake that does not remove objects from the collection class when the objects are no longer needed. This mistake usually results in a very large collection class. There are currently two main ways to analyze this memory leak.
A first way is simply counting the number of objects of each class. The first way does not require a complex algorithm, so is a fast technique. The first way may be able to identify objects which are not being cleaned up, but does not give a user any information about a thread, a method and an object that are causing a memory leak. Since the first way is fast, it can be performed at runtime, inside a runtime environment (e.g. the Java Virtual Machine). In addition, the first way can be performed outside a runtime environment such as a dump of a heap (i.e., transferring contents of a heap in a main memory to a file). Examples:
BEA® JRocket® Memory Leak Detector (http://e-docs.bea.com/jrockit/tools/usingmmleak/index.html)
A depth first search (DFS) is a method of traversing or searching a tree structure (e.g., a binary tree, heap) to reach all nodes in the tree. Consider a tree shown in
Current node: A
Get children of this node: B and C
Move down to first child: B
Get children of this node: D and E
Move down to first child: D
Get children of this node: none
Move back up to parent: B
Move down to next child: E
etc.
A second way is walking (i.e., searching) a heap (i.e., a traditional main memory is divided to two sections: stack—storing code currently executing (small area); heap—storing all other code of a program and storing all saved data (large area)) to ascertain which objects are referencing which other objects, and hence how much memory the objects are referencing. The second way is performed by means of a depth first search (DFS). There are a number of tools that utilize the second way: HeapRoots (http://www.alphaworks.ibm.com/tech/heaproots), HeapAnalyzer (http://www.alphaworks.ibm.com/tech/heapanalyzer), and FindRoots (http://www-1.ibm.com/support/docview.wss?rs=3182&context=SSSTCZ&dc=D400&uid=swg24009436&loc=en_US&cs=UTF-8&lang=en). The second way (i.e., a method utilizing the DFS) has an advantage that it provides more useful information than the first way. Besides, the second way (i.e., a method utilizing the DFS) provides a chain of objects that are related to a memory leak and an amount of memory referenced. This information is not provided by the first way. However, the second way has a disadvantage that, because the second way involves maintaining state information of each object (e.g., an amount of memory referenced by each object) while making a traversal of the heap, the second way uses very large amounts of memory. Therefore, the second way can only be used outside a runtime environment (e.g., an executing a virtual machine state which provides software services for processes or programs while a computer is running), acting on a dump of a heap.
Thus, it is highly desirable to provide a memory leak analysis that uses a small amount of memory space, provides useful information (e.g., a chain of objects, an amount of memory referenced), and is executable at a runtime environment.
It is therefore an object of the present invention to provide a method, system, computer program product, and computer program storage device for performing a memory leak analysis inside a virtual machine.
Most runtime memory leaks are caused by a program storing objects in a collection class and then not removing the objects, leading to an ever growing collection class. Thus, after reachabilities (i.e., a reachability of an object means sum of sizes of all child objects plus a size of the object itself) of objects in a heap have been calculated, a specific pattern (i.e., a single object which references to a number of other objects, such that the reachability of the single object is large) is checked per each object in the heap.
Rather than calculating the reachabilities of all objects on the heap and then applying this pattern (i.e., finding a single object which references to a number of other objects, such that the reachability of the single object is large), the pattern can be applied to a current object (i.e., an object that is currently visited when performing DFS algorithm) as traversing the heap. This technique (i.e., applying the pattern as traversing the heap) has an advantage that this technique radically reduces an amount of data that needs to be stored at a certain time. By applying the pattern inside a running virtual machine, additional information (e.g., data in stack) is available. One embodiment of the present invention makes applying the pattern far simpler by throwing away data in the stack when it is determined that there is no memory leak on an object in the heap. One embodiment of the present invention demonstrates a way of applying a depth first search on a memory leak analysis within an executing virtual machine.
It is highly desirable to be able perform memory leak analysis inside a virtual machine, for two reasons:
In one embodiment, there is provided a method for performing a memory leak analysis inside a virtual machine comprising:
accessing a heap in a main memory, a node in the heap representing an object;
building a list of root objects from thread stacks and class statics, a thread stack locating in a stack in the main memory, a thread having a thread stack, class statics storing static classes that cannot be discarded;
executing a depth first search (DFS) algorithm on the heap from a root object in the list of root objects, a thread stack, or class statics;
initializing a variable reachability and a variable largest child reachability to zero;
calculating a value of the variable reachability of a current object being visited;
determining a value of the variable largest child reachability of the current object being visited;
comparing the value of the variable reachability of the current object being visited to a first threshold;
comparing the value of the variable largest child reachability of the current object being visited to a second threshold; and
when the value of the variable reachability of the current object being visited is larger than the first threshold and when the value of the variable largest child reachability of the current object being visited is less than the second threshold, determining the current object being visited as a source of a memory leak.
In one embodiment, there is provided a system for performing a memory leak analysis inside a virtual machine comprising:
means for accessing a heap in a main memory, a node in the heap representing an object;
means for building a list of root objects from thread stacks and class statics, a thread stack locating in a stack in the main memory, a thread having a thread stack, class statics storing static classes that cannot be discarded;
means for executing a depth first search (DFS) on the heap from a root object in the list of root objects, a thread stack, or class statics;
means for initializing a variable reachability and a variable largest child reachability to zero;
means for calculating a value of the variable reachability of a current object being visited;
means for determining a value of the variable largest child reachability of the current object being visited;
means for comparing the value of the variable reachability of the current object being visited to a first threshold;
means for comparing the value of the variable largest child reachability of the current object being visited to a second threshold; and
means for determining the current object as a source of a memory leak, when the value of the variable reachability of the current object being visited is larger than the first threshold and when the value of the variable largest child reachability of the current object being visited is less than the second threshold.
In another embodiment, upon determining an object as a source of memory leak, a reference to the object, a reachability of the object, and largest child reachability of the object (i.e., largest reachability among children of the object) in stack are provided to a user for debugging.
In another embodiment, upon determining that an object is not a source of memory leak, a reference to the object, a reachability of the object, and largest child reachability of the object in stack are removed.
The objects, features and advantages of the present invention will become apparent to one skilled in the art, in view of the following detailed description taken in combination with the attached drawings, in which:
Hereinafter, embodiments of the present invention will be described in detail with reference to the accompanying drawings.
A main memory is divided into two sections:
To facilitate a memory leak analysis, one embodiment of the present invention defines several variables as the following:
In one embodiment, the stack also stores a reference (i.e., a relation between objects in which one object designates, or acts as a means by which to connect to or link to, another object) to an object that is currently processed by a DFS algorithm. For example, in
A memory leak pattern is usually a collection class with a large number of objects, each of which has a small reachability compared to the collection class as a whole. Each of these objects is a child of the collection class. Since a memory leak is usually caused by a programming mistake that does not remove objects from a collection class when the objects are no longer necessary, the collection class usually results in a very large collection. Therefore, by calculating a largest child reachability of an object and comparing the largest child reachability of the object to a reachability of the object, it can be determined whether the object is a source of a memory leak or not. For example, if a largest child reachability of an object is 60% of a reachability of the object, the object is unlikely to be a source of a memory leak. However, if a largest child reachability of an object less than 50% of a reachability of the object, the object is likely to be a source of a memory leak.
In one exemplary embodiment, in
(Assume that each object has a unit size 1. A variable “count”, a variable “count on entry” of each object, a variable “reachability” of each object, a variable “largest child reachability” of each object are initialized to zero
When a node E is fully processed (e.g., all children of the node E is discovered), a reachability of the node E is calculated as 6. The largest child reachability of the node E has been calculated as 1. Thus, by applying a memory leak analysis pattern (i.e., looking for a collection class with a large reachability with many children, each of which has a small reachability), the node E can be determined as a source of a memory leak due to a large “reachability” and a small “largest child reachability”. Though this walking the heap (e.g.,
Storing the two piece information for every single node can be avoided by throwing away the information of an object after the object is determined not as a source of a memory leak by applying a memory leak analysis pattern as walking the heap. There is a memory leak if there is one node that has a large reachability that is composed of many children, each of which has noticeably smaller reachability. For example, if a largest child reachability of an object is less than 50% of a reachability of the object, the object can be a source of a memory leak. Therefore, if a reachability of a current object (i.e., an object that is currently processed or visited by a DFS algorithm) and reachabilities of children of the current object are known at a given time, a memory leak analysis can be applied. If a memory leak is not found at an object, information (e.g., reachability) of the children of the object can be thrown away. Then, by moving to a parent node of the object, a reachability of the parent node is compared to reachabilities of children of the parent node.
In one embodiment, the reachability of each object can be stored in a stack that represents a path to a currently processing node. Since a reachability of an object is compared to a largest child reachability of the object, the largest child reachability can be stored as an additional information in the stack. In another embodiment, without storing the largest child reachability as additional information, a reachability of an object is compared to all children's reachabilities to find out if the object is a source of a memory leak or not.
In one exemplary embodiment, if a DFS algorithm is executed up to an object D (i.e., the object D is fully processed), the stack has information as like Table 2.
By applying a memory leak analysis (e.g., determining whether an object has a large reachability with many children, each of which has a small reachability), the object D is determined not as a source of a memory leak. Then, the information of the object D is discarded in the stack. Table 3 shows information in stack after information of the object D is discarded.
After the DFS algorithm processes objects E, G, H, I, J, and K, the stack has following information as like Table 4 (information of the objects G, H, I, J, and K has been discarded after being determined not as a source of a memory leak).
When the object E is fully processed (e.g., right after all children of the node E is discovered), a memory leak analysis is applied for the object E and then the object E is determined that the object E can be a source of a memory leak (i.e., a reachability of the object E is large (6); a largest child reachability of the object E is less than 50% of the reachability of the object E; So, it is determined that the object E can be a source of a memory leak).
By throwing away information of an object when the object is determined not as a source of a memory leak, an amount of information that needs to be stored in the stack has been reduced from two piece information per every single node to two or three piece information per objects that are currently processed.
However, an amount of a required memory space can be further reduced by not saving a reachability of an object in the stack. In one embodiment of the present invention, the stack stores “count on entry” and “largest child reachability” of currently being processed objects. In another embodiment, the stack stores “reference to the object”, “Count on entry”, and “Largest child reachability”. To achieve this (i.e., not saving reachability), a memory leak analysis is applied as soon as a reachability of an object is calculated (e.g., by being fully processed). If an object is found as a source of a memory leak, a reachability value of the object is provided to a user (e.g., a programmer) along with reference(s) to the object and a largest child reachability of the object. If an object is found not as a source of a memory leak, a reachability value of the object discarded along with a reference to the object and a largest child reachability of the object. In one embodiment, every time a reachability of an object is calculated or updated, a reachability of an object is compared to a current largest child reachability of a parent of the object. If the reachability of the object is larger than the current largest child reachability of the parent of the object, the reachability of the object is set to the largest child reachability of the parent of the object.
In one exemplary embodiment, when starting to execute a DFS algorithm on
While performing the DFS algorithm, children are discovered and “count on entry” is entered for each child in the stack. Table 6 shows a stack condition just before D is fully processed.
When an object with no more unprocessed children (e.g., a node D) is reached, the variable “Count” is increased by a size of the object. In
This exemplary embodiment reduces a memory space required to perform a memory leak analysis by throwing away data of an object after the object is determined that the object is not a source of a memory leak. At any time, the stack stores three piece information (e.g., “reference to the object”, “count on entry”, “largest child reachability”) for each object in a chain of objects that is currently processing.
After moving to an object E, a reachability of each child of the object E is calculated. After calculating a reachability of a last child (e.g., an object K) of the object E, the stack has following information like Table 8.
After the object E is fully processed (i.e., right after all children of the object E are fully processed), the variable “Count” is incremented by a size of the object E (e.g., Variable “Count” becomes 7). Then, a memory leak analysis applied on the object E. Because the object E has a large reachability and a largest child reachability is small (e.g., a reachability of the object E: 6, a largest child reachability: 1), the object E is determined as a potential source of a memory leak. Then, a current stack information (e.g., Table 8 including references to the object (e.g., a node A, a node B, and a node E)) and a reachability of the object E are provided to a programmer to find a bug causing the memory leak.
In one embodiment, an object is considered a potential memory leak if following two conditions are true:
In one embodiment, a memory leak analysis (i.e., looking for an object with a large reachability with many children, each of which has a small reachability) is applied outside a virtual machine. If a memory leak analysis is applied outside a virtual machine (i.e., a software implementation used to run programs that are written by a non-operating system specific intermediate code (e.g., Java or .NET); Once the programs are interpreted by an interpreter, the programs can run on any operating system with a virtual machine), a DFS algorithm may start at any section of a heap. To execute a memory leak analysis outside a virtual machine, whenever a node is visited, the node is marked as visited and a reachability of the node is recorded in the node. Then, another node that has not been marked is processed. This embodiment requires an entire structure of the heap because a reachability has to be stored at every single node. This embodiment requires a lot of memory space to store a reachability at every single node in the heap.
When a memory leak analysis is performed outside a virtual machine, if a reachability is not stored at each node in the heap, a memory leak may not be discovered. For example, while starting to execute a DFS algorithm on
In one embodiment, a memory leak analysis is performed inside a virtual machine. Working inside a virtual machine enables to access additional information such as thread stacks (i.e., Most modern programs are composed of multiple threads of execution; Stack is actually composed of multiple section; As one section in the stack is used by one thread, each section is called a thread stack) and class statics (i.e., Class statics are a way for a programmer to define information that must be retained at all times; Class statics stores static classes that cannot be disposed by a garbage collector).
In one exemplary embodiment,
Therefore, performing a memory leak analysis in a virtual machine enables to access thread stack(s), class static(s), and/or a list of root objects. By utilizing the thread stack(s)), class static(s), and/or a list of root objects, a DFS algorithm can be started at root objects that are currently processed by a program. Though performing a DFS algorithm at root objects can make a few children of an object be visited first before the object is visited, upon reaching the object, the object can be properly determined as a source of memory leak. Because the number of the children visited or processed first does not affect calculating a reachability of an object that has a lot of children, most of which are referenced by only the object. Therefore, upon calculating a reachability of the object, it can be properly determined whether the object is a source of a memory leak or not. Furthermore, performing a memory leak analysis in a virtual machine enables to remove an object and its related data from a stack, when the object is determined not as a source of a memory leak. Therefore, performing a memory leak analysis in a virtual machine reduces a required memory space. In addition, while performing a DFS algorithm and a memory leak analysis, no change is made to a structure of the heap 110.
If the root object is not processed, at step 215, a variable “Count” is initialized to 0. At step 220, a reference to the root object is stored in a stack. The root object is set to a current object (i.e., an object that is currently visited or processed by a DFS algorithm). At step 225, it is checked whether there are unprocessed children (e.g., not visited children) of the current object (e.g., the root object). At step 230, if there is an unprocessed child, the unprocessed child is set to the current object. At step 235, a reference to the unprocessed child is stored in the stack. A current value of the variable “Count” is stored in the stack as a value of the variable “Count on entry” of the unprocessed child. Then, by going back to step 225, it is checked whether there are unprocessed children of the current object (e.g., the unprocessed child). If it is determined that there is no unprocessed child, at step 245, it is checked whether only one reference (e.g., a reference to an object) is left in the stack. If there is only one reference in the stack, it is checked whether there are more root objects in the thread stacks 10, class statics 20, or a list of root objects 30 by going back to step 205.
If more than one reference are left in the stack, at step 250, the variable “Count” is incremented by a size of the current object. At 255, a reachability of the current object is calculated by subtracting a value of a variable “Count on entry” of the current object from a current value of a variable “Count”. At step 260, the reachability of the current object is compared to a first threshold (e.g., 100 megabytes). At step 265, the largest child reachability of the current object is compared to a second threshold (e.g., half of the reachability of the current object). When the reachability of the current object is larger than the first threshold and the largest child reachability of the current object is less than a second threshold, it is determined that the current object is a potential source of a memory leak. At step 270, when an object is determined as a potential source of a memory leak, references to the object (e.g., a chain of objects before reaching the object), the reachability of the object, and the largest child reachability of the current object are provided to a user via an output device (e.g., a display device or a printing device). At step 260, if the reachability of the current object is less than or equal to the first threshold, it is determined that the current object is not a source of a memory leak. At step 265, if the largest child reachability of the current object is larger than or equal to a second threshold, it is determined that the current object is not a source of a memory leak.
At step 275, the current object's data (e.g., a reference to the current object, a variable “Count on entry” of the current object, a variable “largest child reachability” of the current object) are removed from the stack. At step 280, the reachability of the current object is compared to a current value of a variable “largest child reachability” of a parent of the current object. At step 285, if the reachability of the current object is larger than a current value of a variable “largest child reachability” of a parent of the current object or if the reachability of the current object is largest among reachabilities of siblings of the current object, a value of a variable “reachability” of the current object is stored in the stack as a value of a variable “largest child reachability” of the parent of the current object. At step 280, if the reachability of the current object is not larger than a current value of a variable “largest child reachability” of a parent of the current object, the reachability of the current object is discarded. Then, a parent of current object is set to a current object and then it is checked whether there is an unprocessed child of the current object by going back to step 225. At step 285, after storing a value of a variable “reachability” of the current object as a value of a variable “largest child reachability” of the parent of the current object, the reachability of the current object is discarded. Then, a parent of current object is set to a current object and then it is checked whether there is an unprocessed child of the current object by going back to step 225.
Although the preferred embodiments of the present invention have been described in detail, it should be understood that various changes and substitutions can be made therein without departing from spirit and scope of the inventions as defined by the appended claims. Variations described for the present invention can be realized in any combination desirable for each particular application. Thus particular limitations, and/or embodiment enhancements described herein, which may have particular advantages to a particular application need not be used for all applications. Also, not all limitations need be implemented in methods, systems and/or apparatus including one or more concepts of the present invention.
The present invention can be realized in hardware, software, or a combination of hardware and software. A typical combination of hardware and software could be a general purpose computer system with a computer program that, when being loaded and executed, controls the computer system such that it carries out the methods described herein. The present invention can also be embedded in a computer program product, which comprises all the features enabling the implementation of the methods described herein, and which—when loaded in a computer system—is able to carry out these methods.
Computer program means or computer program in the present context include any expression, in any language, code or notation, of a set of instructions intended to cause a system having an information processing capability to perform a particular function either directly or after conversion to another language, code or notation, and/or reproduction in a different material form.
Thus the invention includes an article of manufacture which comprises a computer usable medium having computer readable program code means embodied therein for causing a function described above. The computer readable program code means in the article of manufacture comprises computer readable program code means for causing a computer to effect the steps of a method of this invention. Similarly, the present invention may be implemented as a computer program product comprising a computer usable medium having computer readable program code means embodied therein for causing a function described above. The computer readable program code means in the computer program product comprising computer readable program code means for causing a computer to effect one or more functions of this invention. Furthermore, the present invention may be implemented as a program storage device readable by machine, tangibly embodying a program of instructions executable by the machine to perform method steps for causing one or more functions of this invention.
It is noted that the foregoing has outlined some of the more pertinent objects and embodiments of the present invention. This invention may be used for many applications. Thus, although the description is made for particular arrangements and methods, the intent and concept of the invention is suitable and applicable to other arrangements and applications. It will be clear to those skilled in the art that modifications to the disclosed embodiments can be effected without departing from the spirit and scope of the invention.
Number | Name | Date | Kind |
---|---|---|---|
5752241 | Cohen | May 1998 | A |
6167535 | Foote et al. | Dec 2000 | A |
6321240 | Chilimbi et al. | Nov 2001 | B1 |
6330556 | Chilimbi et al. | Dec 2001 | B1 |
6381735 | Hunt | Apr 2002 | B1 |
6560773 | Alexander et al. | May 2003 | B1 |
6658652 | Alexander et al. | Dec 2003 | B1 |
6675379 | Kolodner et al. | Jan 2004 | B1 |
6934615 | Flann et al. | Aug 2005 | B2 |
6986117 | Teig et al. | Jan 2006 | B1 |
7069281 | Garthwaite | Jun 2006 | B2 |
7092978 | Garthwaite | Aug 2006 | B2 |
7100003 | Betancourt et al. | Aug 2006 | B2 |
7234080 | Cirne et al. | Jun 2007 | B2 |
7293051 | Printezis et al. | Nov 2007 | B1 |
7313661 | Dmitriev | Dec 2007 | B1 |
7325106 | Dmitriev et al. | Jan 2008 | B1 |
7389395 | Garthwaite et al. | Jun 2008 | B1 |
7412466 | Garthwaite | Aug 2008 | B1 |
7434206 | Seidman et al. | Oct 2008 | B2 |
7480782 | Garthwaite | Jan 2009 | B2 |
7526750 | Andrews et al. | Apr 2009 | B2 |
7584232 | Guo | Sep 2009 | B2 |
7594111 | Kiriansky et al. | Sep 2009 | B2 |
7603704 | Bruening et al. | Oct 2009 | B2 |
7802232 | Zorn et al. | Sep 2010 | B2 |
7827538 | Trotter | Nov 2010 | B2 |
7870170 | Achanta et al. | Jan 2011 | B2 |
20020072830 | Hunt | Jun 2002 | A1 |
20040078540 | Cirne et al. | Apr 2004 | A1 |
20040154016 | Randall | Aug 2004 | A1 |
20040167945 | Garthwaite | Aug 2004 | A1 |
20040167947 | Garthwaite | Aug 2004 | A1 |
20040181562 | Findeisen | Sep 2004 | A1 |
20040181782 | Findeisen | Sep 2004 | A1 |
20040193349 | Flann et al. | Sep 2004 | A1 |
20050114844 | Betancourt et al. | May 2005 | A1 |
20060206885 | Seidman et al. | Sep 2006 | A1 |
20060247907 | Qadeer et al. | Nov 2006 | A1 |
20060253845 | Achanta et al. | Nov 2006 | A1 |
20070027942 | Trotter | Feb 2007 | A1 |
20080082968 | Chang et al. | Apr 2008 | A1 |
20080172708 | Perry et al. | Jul 2008 | A1 |
20080271104 | Perry et al. | Oct 2008 | A1 |
20080271105 | Perry et al. | Oct 2008 | A1 |
20080276293 | Perry et al. | Nov 2008 | A1 |
20090089842 | Perry et al. | Apr 2009 | A1 |
Number | Date | Country | |
---|---|---|---|
20090327373 A1 | Dec 2009 | US |