Memory leakage in Java programs

Source: Internet
Author: User

Java Memory leakage is not a new topic. Jim Patrick wrote this article as early as 2001. However, this does not mean that Java Memory leakage is an outdated or even unimportant topic. On the contrary, Java Memory leakage should be a must for every programmer concerned about program robustness and high performance.
This article will reveal when to pay attention to memory leaks and how to prevent them.
Abstract: Memory leakage also exists in Java programs? Of course. In contrast to popular ideas, memory management is still a concern for Java programming. In this article, you will learn why Java memory leaks occur and when to pay attention to these leaks. You will also learn a quick and practical course to cope with memory leaks in your project.
How is the memory leakage in Java programs?
Most programmers know that one of the benefits of using a programming language similar to Java is that they don't have to worry about memory allocation and release. You only need to simply create objects. When they are no longer needed by the program, Java will remove them through a mechanism called garbage collection. This process means that Java has solved a tough problem that troubles other programming languages-the terrible memory leakage. Is that true?
Before in-depth discussion, let's first review how garbage collection actually works. The purpose of the garbage collector is to find objects that are no longer needed by the program and remove them when they are no longer accessed or referenced. The Spam collector scans all referenced nodes from the root node of the class that runs throughout the life cycle of the program. When traversing a node, it traces objects that are actively referenced. Objects that are no longer referenced meet the garbage collection conditions. When these objects are removed, the memory resources they occupy will be returned to the Java Virtual Machine (JVM ).
Therefore, Java code does not require programmers to clean up memory management. It collects garbage for objects that are no longer in use. However, it should be noted that the key to garbage collection is that an object is counted as not used when it is no longer referenced. This concept is described.

Indicates two classes with different lifecycles when a Java program is executed. Class A is first instantiated. It takes A long time to exist and almost runs through the lifecycle of the entire process. At A certain time point, Class B is created, and Class A adds A reference to the new class. Suppose Class B is a user interface component used to display and return USER commands. Although Class B is no longer used, if Class A's reference to Class B is not cleared, Class B will continue to exist and occupy memory space, even if the next garbage collection is executed.
When should I pay attention to memory leakage?
If your program encounters a java. lang. OutOfMemoryError after a period of execution, the memory leakage is undoubtedly the most questionable. In addition to this obvious situation, when should we consider Memory leakage? Perfectionist programmers will answer that all memory leaks need to be reviewed and changed. However, before jumping to this conclusion, you need to consider other factors, including the life cycle of the program and the size of Memory leakage.
Consider the situation where the Garbage Collector may never be executed during the life cycle of a program. There is no guarantee when the JVM will call garbage collection-even if the program explicitly calls System. gc (). Generally, the garbage collector does not run automatically until the program requires more memory than the available memory. In this case, JVM first tries to call the Garbage Collector to obtain more available memory. If this attempt still fails to release enough resources, JVM will get more memory from the operating system until the maximum allowed memory is reached.
For example, a small Java application is used to display some simple configuration-modified User interface elements, causing memory leakage. The Garbage Collector may not be called until the program is closed, because the JVM may always have enough memory to create all the objects required by the program. Therefore, in this case, even some dead objects still occupy the memory when running the program, but this does not affect the actual application.
If the Java code in Development runs on the server 24 hours a day, the memory leakage will be much more obvious than the preceding Configuration tool. Even with the smallest Memory leakage in the Code, all available memory will eventually be used up during continuous operation.
On the contrary, a large number of temporary objects (or a small number of objects that occupy a large amount of memory) are allocated even if a program only lives for a short time. The reference is not canceled when these objects are no longer needed, such Java code will also reach the memory limit.
The last noteworthy problem is that you don't have to worry too much about memory leakage caused by Java programs. Java Memory leakage should not be considered as dangerous as it occurs in other languages. For example, the loss of C ++ memory will never be returned to the operating system. In Java applications, we give the JVM all the objects that are no longer needed but occupy memory resources. So theoretically, once the Java program and its JVM are closed, all allocated memory will be returned to the operating system.
How to determine whether a program has a memory leak
Check whether a Java program running on Windows NT has memory leakage. You can simply observe the memory settings in the task manager when running the program. However, after observing some running Java programs, you will find that they use more memory than local applications. Some Java projects I have developed enable 10 to 20 MB of system memory. Compared with this number, the Windows Explorer program that comes with the local operating system uses 5 MB.
Another thing to note about the memory usage of Java programs is that the typical program running on the IBM JDK1.1.8 JVM seems to have swallowed up more and more system memory at its runtime. The program never seems to return some memory to the operating system until a very large physical memory is allocated to it. Will this be a sign of Memory leakage?
To understand what is going on, we need to be familiar with how JVM uses the system memory as its own heap. When running java.exe, you can use some specific options to control the startup capacity and maximum capacity (-ms and-mx) of the garbage collection heap ). Sun's JDK 1.1.8 uses the 1 MB startup setting and the 16 MB maximum setting by default. By default, ibm jdk 1.1.8 uses half of the physical memory capacity of the machine as the maximum setting. These memory settings have a direct impact on the practice of JVM memory overflow. At this time, JVM may continue to increase the heap memory, rather than waiting for the end of a garbage collection.
Therefore, we need better tools than task monitoring programs to find and ultimately eliminate memory leaks. The memory debugging program can be used when you want to detect memory leaks (see references below. These programs usually give you information about the number of objects in the heap memory, the number of each object instance, and the memory used by the object. In addition, they provide useful views that show references and references for each object so that you can track the source of memory vulnerabilities.
Next, I will show you how to use Sitraka Software's JProbe debugging tool to detect and eliminate memory leaks. I hope it will inspire you to deploy these tools and successfully eliminate memory leaks.
An example of Memory leakage
This example shows a problem with a commercial edition application developed by our department. The problem was found by testers after working on JDK 1.1.8 for several hours. Code and packages related to this Java application are developed by several programmers from different teams. I suspect the cause of Memory leakage in the program is caused by some programmers who do not really understand the code developed by other (teams. The Java code in the discussion allows you to create a Palm personal digital assistant application without having to write local Palm OS code. By using the graphical interface, you can create forms, populate them with controls, and connect control events to create Palm applications. The tester found that the Java application eventually experienced a memory overflow-delay in creating and deleting forms and controls. Developers did not find this problem because their machines (compared to Palm) have more physical memory.
To discuss this problem, I used JProbe to determine the existence of the problem. Even with the powerful tools and memory snapshots provided by JProde, the investigation is still a tedious and repetitive process. It involves first determining the cause of Memory leakage, then making code changes and verifying the effect.
JProbe has several options to control what information will be recorded during a debugging session. After some experiments, I determined that the most effective way to obtain the required information is to turn off performance data collection and focus on captured heap data. JProbe provides a view called runtime heap summary to display the number of heap memory used by Java applications over a period of time. It also provides a toolbar button to force the JVM to execute garbage collection as needed-to see if a given instance of a class is not required by a Java application, this function is very useful. Shows the Heap Storage used in a period of time.

In the heap usage diagram, the blue part indicates the allocated heap space. After I started the Java program, it reached a stable point, and I forced the Garbage Collector to execute it, represented by a sudden drop of the blue curve before the Green Line (this green line indicates a checkpoint is inserted ). Next, I first added and deleted four forms and called the Garbage Collector again. The fact that the horizontal line of the blue curve after the checkpoint is higher than the horizontal line of the blue curve before the checkpoint tells us that memory leakage is likely to occur, this program has returned to the initial State of a simple and visible form. I checked the instance to confirm the leak. In short, the results show that the number of FormFrame classes (the main UI class of the form) is increased by four after the checkpoint.
Find the reason
To isolate the problems submitted by testers, the first step is to provide some simple and repeated test cases. The example above is used as an example. I found that simply adding a form, deleting the form, and forcing the spam collector results in that some instances associated with the deleted form are still alive. This problem is obvious in the JProbe instance summary view, which counts the number of instances of each class in the heap memory.
To locate the reference of a specific instance when the garbage collector is working, I used the reference image of JProbe, as shown in, to determine which classes are still referencing the deleted FormFrame class. This is one of the clever ways to debug this problem. I found that many different objects are still referencing useless objects. It is quite time-consuming to find out which quote actually caused this problem through trial and error.
In this case, the root class (the red one in the upper left corner) is the origin of the problem. The class highlighted in blue on the right is the traced FormFrame class.

For this specific example, the culprit is a font management class that contains a static hash table. After tracking the reference list, I found that the root node is a static hash table that stores the fonts used by each form. Various forms can be scaled in or out independently. Therefore, the hash table contains a vector containing all fonts of each specified form. When the scaling view of the form changes, the vector with the font is obtained and the appropriate scaling factor is selected to adapt to the font size.
The problem with this font manager is that when a form is created, when the code puts the font vector into the hash table, it does not define the removal of the vector when the form is deleted. Therefore, the static hash table that exists throughout the life cycle of the application never removes the key value pointing to each form. Therefore, all forms and their associated classes are left in the memory.
Problem correction
A simple solution to this problem is to add a method to the font manager to allow the remove () method of the hash table to be called when the user deletes the form. The added removeKeyFromHashtables () method is as follows:
[Java]
Public void removeKeyFromHashtables (GraphCanvas graph ){
If (graph! = Null ){
ViewFontTable. remove (graph); // remove key from hashtable
// To prevent memory leak
}
}

Then, I added a call to this method in the FormFrame class. FormFrame uses the Swing internal framework to implement the form UI. Therefore, the call to the font manager is added to the method executed when the internal framework is completely closed, as shown below:
[Java]
/**
* Invoked when a FormFrame is disposed. Clean out references to prevent
* Memory leaks.
*/
Public void internalFrameClosed (InternalFrameEvent e ){
FontManager. get (). removeKeyFromHashtables (canvas );
Canvas = null;
Setmediatopicon (null );
}

After I modify the code, I use a debugging tool to check the number of objects associated with the deletion form when the same test case is executed.
Memory leakage prevention
You can pay attention to some common problems to prevent memory leakage. Container classes, such as hash tables and vectors, are common locations that cause memory leakage. Especially when these classes are declared static and survive the entire lifecycle of the application.
Another common (causing memory leakage) problem is that when you register a class as an event listener, you do not consider deregistering it when the class is no longer needed. Also, set the member variables pointing to other classes to null when appropriate.
Conclusion
Looking for the cause of Memory leakage may be a tedious process, but it is not mentioned that this will require special debugging tools. However, once you are familiar with the tools and modes of tracing object reference, you will be able to track Memory leakage. In addition, you will gain some valuable skills, which not only saves your project programming investment, but you will also have the vision to find out the programming practices that can prevent memory leakage in future projects.
Related Materials
JProbe of Quest Software
Borland Optimizeit Enterprise
Paul Moeller's Win32 Java Heap Inspector

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.