Sun JDK OOM
Bluedavyjvm JVM, Oom, Sun jdk oom no comments
Java's Automatic Memory Management Mechanism brings a lot of convenience to developers. During design and development, you do not have to consider how much memory to allocate, remember to recycle the memory, etc, but it also brings a variety
The most typical problem is oom. Most Java developers probably see errors such as Java. Lang. outofmemoryerror.
In this article, we will introduce the OOM and OOM examples in Sun JDK, how to find and solve the cause of Oom, and how to process OOM in Sun JDK code.
Download PDF from: http://blog.bluedavy.com/open/Sun-JDK-OOM.pdf
1 OOM type
When running Sun JDK, the Java program may encounter the following OOM errors:
Java. Lang. outofmemoryerror: Unable to create new Native thread
When new
If a thread cannot be created, this error is thrown. If a thread must be created successfully in JDK, the Java Process exits. If the thread is a user thread, throw only
Oom, which cannot be created because too many threads are created and the memory is exhausted. Generally, you can reduce the number of created threads, or you can reduce the stack size occupied by the-XSS thread to reduce the Java
External memory consumption.
Java. Lang. outofmemoryerror: Request bytes for. Out of swap space?
When the JNI module or JVM performs malloc operations (such as mark during GC), the off-heap memory needs to be consumed. For example, the address space occupied by the Java Process exceeds the limit.
(For example, if windows: 2g, Linux: 3G), or the physical memory and swap are used up, this error occurs. When this error occurs, the Java Process exits.
Java. Lang. outofmemoryerror: Java heap Space
This is the most common OOM error. When an object or array is created through new, for example, Java heap space is insufficient (due to the lack of new generation, it is not enough to trigger minor GC, and it is not enough to trigger full GC ), this error is thrown.
Java. Lang. outofmemoryerror: GC overhead limit execeeded
When creating an object or array through new, such as Java
If heap space is insufficient, and GC takes 98% of the total time of the program, and heap space is less than 2%, this error is thrown to avoid full
GC is always executed. You can use usegcoverheadlimit to determine whether to enable this policy. You can use gctimelimit and gcheapfreelimit to control this policy.
Percent.
Java. Lang. outofmemoryerror: permgen Space
When the class is loaded, if the permgen space is insufficient after full GC, this error is thrown.
For the above OOM errors, the out of swap space may cause serious consequences, because this will cause the Java Process to exit, and other types of errors, as long as they are not thrown in the main thread, this will not cause the Java Process to exit.
2 OOM example, cause search and Solution
For the class and source code of these examples, refer.
When a Java program is running, there are many causes of Oom, some of which are easier to find out the cause, and some are very difficult. Here are some examples of oom.
Example 1
Run com. bluedavy. oom. javaheapspacecase1 with the-xms20m-xmx20m-xmn10m-XX: + useparallelgc Parameter
After running, a large amount of full GC information can be seen in the output log, and:
Java. Lang. outofmemoryerror: GC overhead limit exceeded
And java. Lang. outofmemoryerror: Java heap Space
Based on the OOM type mentioned above, we can know that this is caused by insufficient Java heap space in the new object or array. For this Oom, we need to know which parts of the program occupy Java heap.
To know which part of the program occupies the Java heap, you must first obtain the information in the Java heap, especially the memory information in oom.
In JDK, you can add-XX: + heapdumponoutofmemoryerror to the startup parameter to obtain the Java
Heap information. When OOM occurs, a java_pid [pid]. hprof file is automatically generated.
Therefore, add the preceding parameter to the startup parameter and run javaheapspacecase1 again. You can see that
Java_pid10852.hprof (because the PID is different, you may see different file names), after obtaining this file, you can
MAT (http://www.eclipse.org/mat/) for analysis.
Use mat to open the above file (by default, mat considers that the heap dump file should end with. Bin, so rename the file or use open
Open file), click dominator_tree, and you can see that sun. Misc. launcher $ appclassloader occupies most of
Memory, continue to open the view, you can see that because the com. bluedavy. oom. Caches has an arraylist, the stored objects occupy most of the memory, so
The OOM solution is to limit the total size of objects in the caches class or the number of objects in the arraylist of the caches class.
In this case, oom is easily generated when cache is used in actual scenarios. The maximum size of all caches and sets should be given, in this way, the cache or collection is too large, resulting in excessive memory consumption and OOM.
Example 2
Run "-xms20m-xmx20m-xmn10m-XX: + heapdumponoutofmemoryerror" to execute "com. bluedavy. oom. javaheapspacecase2 ".
After running, a large number of full GC and Java. Lang. outofmemoryerror: Java heap space are displayed in the output log.
Similarly, first use mat to open the hprof file to be analyzed, and you are surprised to find that nothing can be seen, Java heap
Space is quite adequate, which is strange. In addition to the ability to automatically dump heap information at Oom, The jmap command can also be used to manually dump the information. As a result, it occurs frequently at runtime.
During full GC and OOM, manually run jmap-dump: file = heap. Bin, format = B
[Pid] generate a heap. binfile, and take the heap. binfile to mat for analysis. The cup is still invisible. Fortunately, another trick is to use it directly.
Jmap
-Histo: check which objects occupy most of the memory and run the command once. [I occupies the most memory, which is useless, because I cannot know which part of the code is created.
I am very lucky to execute it several times. I suddenly saw that com. bluedavy. oom. case2object occupied the largest memory, so I found out where the object was created in the code,
We found that a thread in the Code has created a large number of case2object and can be modified.
In this example, we can see that when analyzing the OOM problem, it is a dump file that depends on OOM, but this file will only appear for the first time in the Java Process.
After the OOM is generated, it will not be generated again. This may cause the real OOM to be masked by the false oom. On the other hand, it depends on the manual operation when the OOM occurs, in fact
Compared to the Cup, because it can only wait until frequent full GC, Oom, first through jmap
-Histo: Let's see which object occupies most of the memory (it needs to be executed several times to ensure correctness). The above example is lucky because it is a custom object, if it is a native type,
The dump file can only be used for analysis.
-Dump manually dumps the heap file and uses mat for analysis. However, the above-mentioned situation may occur, that is, nothing can be seen in mat analysis. At most, you can only see it.
In unreachable objects, some objects occupy most of the memory, and usually all of them are native.
-Histo sees that the native type occupies a large amount, and jmap dump sees Java heap.
If space is not satisfied, it can only be said to have a cup. In this case, the only thing that can be done is to capture all exceptions and print them to determine which line of OOM code is thrown.
Example 3
Run "-xms20m-xmx20m-xmn10m-XX: + heapdumponoutofmemoryerror" to execute "com. bluedavy. oom. javaheapspacecase3 ".
You can see a large number of Java. Lang. outofmemoryerror: Java heap
Space: Put the generated hprof file into mat for analysis. Fortunately, we can see that Java heap space is full. This is easy to do. Click Dominator.
Tree View, we can see that there are a bunch of threads, each occupying a certain amount of memory, resulting in oom. There are four ways to solve OOM in this example: one is to reduce the number of processing threads, and the other is to process
The memory consumed by the thread; the third is to increase the processing speed of the thread; the fourth is to increase the number of machines and reduce the number of requests required by a single machine.
The above situation is easy to appear when the system is slow to process.
Example 4
Run "-xms20m-xmx20m-xmn10m-XX: + heapdumponoutofmemoryerror" to execute "com. bluedavy. oom. javaheapspacecase4 ".
You can see a large number of Java. Lang. outofmemoryerror: Java heap
Space, put the generated hprof file into mat for analysis, we can see that handlers in taskexecutor occupies a large amount of memory, analyze the code, it is found that because
If handler is not cleared after the task is processed, the OOM problem can be solved by modifying the handler.
This is a typical example of Memory leakage. If you accidentally hold an object that is supposed to release the reference, it will cause memory leakage, which deserves special attention when writing Java programs.
Example 5
Run com. bluedavy. oom. cannotcreatethreadcase with-xms1536m-xmx1536m-xss100m.
You can see java. Lang. outofmemoryerror: Unable to create new Native thread in the console.
In this case, you need to check the current-XSS size. For example, in this example,-XSS is too large, and 20 threads cannot be created, therefore, the solution is to reduce the size of-XSS.
Small; If XSS uses the default value, you can use jstack to check whether too many threads have been created in the Java Process or
Heap is too large, resulting in no memory left in the OS, so that no threads can be created.
Example 6
The out of swap example is too difficult to mention and is not listed here. For out of swap Oom, You need to first check whether it is caused by Java
The heap setting is too large, resulting in insufficient physical memory + swap areas. If not, you need to know where the off-heap memory is occupied. You can use Google-perftools.
Trace the code calling malloc and the memory consumption ratio. After tracing, you can continue to find the cause.
In general, out of swap is usually the most difficult to query oom. Because it directly exits the Java Process, it must be integrated with core
The dump file and the hs_err_pid [pid]. log file are analyzed. The most important thing is to find out what code has caused native, just like querying Java heap.
Heap consumption.
Example 7
When the permgen space is full, oom is usually solved by simply expanding the permsize.
To sum up the above example, the most important thing about oom is to find out which part of the code is consumed Based on the OOM type.
For Java heap space OOM and GC overhead limit exceeded
Dump File and jmap-histo for analysis. In most cases, you can use heap dump to analyze the cause, but there are also a few cases where heap
Dump cannot analyze the cause, while jmap
-Histo can see that a native type occupies most of the memory, which is very complicated. It can only be found by carefully checking the code and capturing outofmemoryerror.
Which part of the code is thrown.
For the out of swap type, it is mainly because the address space exceeds the limit or the external memory is insufficient. First, check whether the Java heap settings are too large, then, you can use Google-perftools to check which code calls malloc and allocate memory out of the heap.
3. How to process OOM in Sun JDK code
In Sun JDK code, different methods are called for processing in different OOM values. Let's take a look at some typical OOM code in JDK.
Failed to create thread
Compiler_thread = new compilerthread (queue, counters );
If (compiler_thread = NULL | compiler_thread-> osthread () = NULL ){
Vm_exit_during_initialization ("Java. Lang. outofmemoryerror ",
"Unable to create new Native thread ");
}
For threads that must be successfully created in JDK, if they fail, the OOM error is printed by calling vm_exit_during_initialization and the Java Process is exited.
For threads that are not required to be successfully created
Throw_msg (vmsymbols: java_lang_outofmemoryerror (),
"Unable to create new Native thread ");
Throw an OOM error message.
Failed to call OS: malloc
Void * P = OS: malloc (bytes );
If (P = NULL)
Vm_exit_out_of_memory (bytes, "Chunk: New ");
Return P;
When OS: malloc or OS: commit_memory fails, an error message is output and the Java Process is exited.
After Java heap allocation fails
Report_java_out_of_memory ("Java heap space ");
This indicates that the VM will not be exited, but an OOM error will be thrown.
For example, if the permgen allocation fails, the code is more intuitive:
Heapword * result = Universe: heap ()-> permanent_mem_allocate (size );
If (result! = NULL ){
Not_product (Universe: heap ()->
Check_for_non_bad_heap_word_value (result, size ));
Assert (! Has_pending_exception,
"Unexpected exception, will result in uninitialized storage ");
Return result;
}
//-XX: + heapdumponoutofmemoryerror and-XX: onoutofmemoryerror support
Report_java_out_of_memory ("permgen space ");
In general, oom is an inevitable phenomenon for a large system. The most important thing is to master the troubleshooting method once OOM occurs. In addition, as the memory becomes more and more popular
Appropriate, cms gc is becoming more and more mature, with 64
Bit operating system, enabling large memory is also an optional method, which can basically avoid memory problems, after all, writing a few lines of code in Java completely consumes a lot of memory.
PS: If you are interested, please refer to Sun's official OOM article:
Http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html