The Java Virtual Machine specification stipulates that the memory of the JVM is divided into several pieces, such as heaps, stacks, program counters, method areas, and so on, and the implementation of the hotspot JVM divides the heap memory into three parts, the Cenozoic, the old, and the persistent belt, which implements the method area as defined The different parts of the memory model will have the corresponding OutOfMemoryError error, and then we will discuss it separately. Java.lang.OutOfMemoryError This error I believe most developers have encountered, the cause of this error is mostly due to the following reasons:
JVM memory is too small, the program is not tight, resulting in too much garbage.
There are several common causes of OutOfMemoryError exceptions:
- The amount of data loaded in memory is too large, such as fetching too much data from the database at one time;
- The collection class has references to objects that are not emptied after use, making the JVM unable to recycle;
- An object entity in the code that has a dead loop or a loop that produces too many duplicates;
- Bugs in third party software used;
- The startup parameter memory value set too small;
Common error tips for this error:
- Tomcat:java.lang.OutOfMemoryError:PermGen Space
- Tomcat:java.lang.OutOfMemoryError:Java Heap Space
- Weblogic:root cause of Servletexception java.lang.OutOfMemoryError
- Resin:java.lang.OutOfMemoryError
- Java:java.lang.OutOfMemoryError
Stack Overflow (stackoverflowerror)
Stack overflow throws a java.lang.StackOverflowError error, which occurs because the stack depth exceeds the maximum allowable depth of the virtual machine when the method runs. This situation is usually caused by a procedural error, such as writing a dead recursion, which is likely to cause this situation. Let's use a code to simulate the memory overflow in this case.
Import java.util.*;
Import java.lang.*;
public class oomtest{public
void Stackoverflowmethod () {
stackoverflowmethod ();
}
public static void Main (String ... args) {
oomtest oom = new Oomtest ();
Oom.stackoverflowmethod ();
}
Running the above code throws the following exception:
Exception in thread ' main ' java.lang.StackOverflowError at
Oomtest.stackoverflowmethod (oomtest.java:6)
Heap Overflow (Outofmemoryerror:java heap space)
Heap memory overflow, the virtual opportunity to throw Java.lang.OutOfMemoryError:Java heap space, when this happens, we need to be based on the memory overflow when the dump file to analyze the specific (need to increase-xx:+ HEAPDUMPONOUTOFMEMORYERRORJVM startup parameters). This problem may occur when there is a memory leak, or it may be a memory overflow.
If memory leaks, we need to find out how the leaked objects are referenced by GC root, and then use the chain of references to specifically analyze the cause of the leak.
If there is a memory overflow problem, this is often the program native needs more memory than we give to the virtual machine configuration of memory, in this case, we can use the big-xmx to solve this problem.
Here's what we can do to illustrate the overflow of this situation by using the following code:
Import java.util.*;
Import java.lang.*;
public class oomtest{public
static void Main (String ... args) {
list<byte[]> buffer = new Arraylist<byte []> ();
Buffer.add (new byte[10*1024*1024]);
}
We run the above code by using the following command:
JAVA-VERBOSE:GC-XMN10M-XMS20M-XMX20M-XX:+PRINTGC Oomtest
The program enters the following information:
[GC 1180k->366k (19456K), 0.0037311 secs]
[Full GC 366k->330k (19456K), 0.0098740 secs]
[Full GC 330k->292k (19456K), 0.0090244 secs]
Exception in thread "main" Java.lang.OutOfMemoryError:Java heap spaces at
Oomtest.main (oomtest.java:7)
From the results of the operation can be seen, the JVM has a minor GC and two major GC, from the major GC output can be seen, the GC after the old area utilization of 134K, and the byte array is 10M, add up to more than the old generation space, so thrown an exception , if you adjust-xms21m,-xmx21m, the GC operation will not be triggered and the exception will not occur.
Through the above experiment in fact also from the side to verify a conclusion: When the object is larger than the new generation of surplus memory, will be directly into the old age, when the old age remaining memory or can not be put down, triggering garbage collection, after collection or can not put down will throw out memory overflow anomaly
Persistent band overflow (Outofmemoryerror:permgen space)
We know that the hotspot JVM implements the method area in the Java Virtual Machine specification through a persistent band, while the Run-time constant pool is stored in the method area, so a persistent band overflow may be an overflow of a running constant-volume pool. It is also possible that the class object saved in the method area is not recycled in time or that the class information occupies more memory than we configure. Throw Java.lang.OutOfMemoryError:PermGen space when a persistent band overflows.
I may have this problem at work in the following scenarios.
With some application server hot deployment, we will encounter a hot deployment several times later found that the memory overflow, this situation is because each hot deployment, the original class has not been unloaded.
If the application itself is large, there are more class libraries involved, but the memory we allocate to the persistent band (set by-xx:permsize and-xx:maxpermsize) can also occur when it is relatively small.
Some third-party frameworks, such as spring,hibernate, implement some enhancements through bytecode generation (such as Cglib), which may require a larger method area for storing dynamically generated class files.
We know that string constants in Java are placed in a constant pool, string.intern () When this method runs, it checks to see if there are any objects in the constant pool that are equal to this string, and if there is a reference to the object directly returning to the constant pool, the string is added to the constant pool. And then returns a reference to the string. Then we can simulate the overflow of the run-time area by String.intern method. Here we simulate this by using the following code:
Import java.util.*;
Import java.lang.*;
public class oomtest{public
static void Main (String ... args) {
list<string> List = new arraylist<string > ();
while (true) {
List.add (Uuid.randomuuid (). toString (). Intern ());}}}
We run the above code by using the following command:
JAVA-VERBOSE:GC-XMN5M-XMS10M-XMX10M-XX:MAXPERMSIZE=1M-XX:+PRINTGC Oomtest
The running input is shown in the following illustration:
Exception in thread "main" java.lang.OutOfMemoryError:PermGen spaces at
Java.lang.String.intern (Native method) At
Oomtest.main (oomtest.java:8)
Through the code above, we successfully simulated the running of a constant-volume pool overflow, from the output of the PermGen space can be seen is indeed a persistent band overflow, which also validated, we said earlier hotspot JVM through the persistence of the implementation of the method area.
Outofmemoryerror:unable to create native thread
Finally, let's look at the error java.lang.OutOfMemoryError:unable to create Natvie thread. When this happens, it is usually caused by the following two kinds of situations:
The number of threads created by the program exceeds the operating system limit. For Linux systems, we can view this restriction by ulimit-u.
The memory allocated to the virtual machine is too large, resulting in too little native memory to create the thread. We all know that the operating system is limited to the memory of each process, we start the JVM, which is equivalent to start a process, if one of our processes consumes 4G of memory, then the remaining memory calculated through the following formula is the memory that can be used to build the line stacks. Line stacks total available memory =4g-(-xmx value)--(-xx:maxpermsize value)--The program counter occupies memory through the above formula we can see that the greater the value of-XMX and MaxPermSize, the smaller the space available to the thread stack, The smaller the number of threads that can be created when the-XSS parameter is configured with the same stack capacity. So if this is the result of unable to create native thread, then either we increase the total memory consumed by the process or reduce the-XMX or-XSS to create more threads.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.