Link Address: http://my.oschina.net/sunchp/blog/369412
1. Background knowledge
1). JVM Architecture
2). JVM run-time data area
The JVM memory structure is related to the following reference:
http://my.oschina.net/sunchp/blog/369707
2. Heap overflow (Outofmemoryerror:java heap space)
The heap is where Java holds object instances.
Heap overflow can be divided into the following two cases, both of which throw the Outofmemoryerror:java heap space exception:
1) Memory leaks
A memory leak is when an object instance is still referenced after it has been created and used, is not released by garbage collection, and accumulates until there is no remaining memory available.
If memory leaks, we want to find out how the compromised object was referenced by GC root, and then use the reference chain to specifically analyze the cause of the leak.
The tools for analyzing memory leaks are: JPROFILER,VISUALVM and so on.
Example:
?
12345678910111213141516 |
package
com.demo3;
import
java.util.ArrayList;
import
java.util.List;
import
java.util.UUID;
public
class
OOMTest {
public
static void
main(String[] args) {
List<UUID> list =
new
ArrayList<UUID>();
while
(
true
) {
list.add(UUID.randomUUID());
}
}
}
|
Run the program with the following command:
?
1 |
java -Xms10M -Xmx10M -XX:-UseGCOverheadLimit OOMTest |
Output Result:
?
12345678 |
Exception in thread
"main"
java.lang.OutOfMemoryError: Java heap space
at sun.security.provider.DigestBase.engineDigest(DigestBase.java:
163
)
at java.security.MessageDigest$Delegate.engineDigest(MessageDigest.java:
576
)
at java.security.MessageDigest.digest(MessageDigest.java:
353
)
at sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:
226
)
at java.security.SecureRandom.nextBytes(SecureRandom.java:
455
)
at java.util.UUID.randomUUID(UUID.java:
145
)
at com.demo3.Test.main(Test.java:
12
)
|
2) Memory Overflow
Memory overflow means that when we create a new strength object, the instance object takes up more memory space than the heap's free space.
If there is a memory overflow problem, this is often the program native needs more memory than we give the virtual machine configuration of memory, in this case, we can use the-XMX to solve this problem.
Example:
?
123456789101112 |
package
com.demo3;
import
java.util.ArrayList;
import
java.util.List;
public
class
OOMTest {
public
static
void
main(String[] args) {
List<
byte
[]> buffer =
new
ArrayList<
byte
[]>();
buffer.add(
new
byte
[
10
*
1024
*
1024
]);
}
}
|
Run the program with the following command:
?
1 |
java -verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC OOMTest |
Output Result:
?
1234567 |
[GC 836K->568K(19456K),
0.0234380
secs]
[GC 568K->536K(19456K),
0.0009309
secs]
[Full GC 536K->463K(19456K),
0.0085383
secs]
[GC 463K->463K(19456K),
0.0003160
secs]
[Full GC 463K->452K(19456K),
0.0062013
secs]
Exception in thread
"main"
java.lang.OutOfMemoryError: Java heap space
at com.demo3.OOMTest.main(OOMTest.java:
10
)
|
3. Persistent belt overflow (outofmemoryerror:permgen space)
The Persistence Band (PermGen space) is where the JVM implements the method area, so the exception is primarily designed to be a constant pool in the method area and the method area.
1). Method area
The method area contains not only the constant pool, but also the meta information of all loaded classes. The Outofmemoryerror:permgen space exception is thrown when there are too many classes loaded and the method area does not fit all loaded meta information. The following are the main scenarios:
With some application server hot deployment, we will encounter a hot deployment a few times after the memory overflow, this situation is because after each hot deployment, the original class was not unloaded.
This can also occur if the application itself is larger and the class libraries involved are more, but the memory that we allocate to the persistence band (set by-xx:permsize and-xx:maxpermsize) is relatively small.
2). Constant pool
Chang (Runtime constrant Pool) specifically places symbolic information in the source code. In addition to the constant values in the constant pool that contain the various basic types defined in the code (such as int, long, and so on) and the object type (such as String and array), there are some symbolic references, such as the fully qualified name of the class and interface, the name and descriptor of the field, and the name and descriptor of the method.
The Outofmemoryerror:permgen space exception is also thrown when the constant pool requires more space than the constant pool's actual space.
For example, a string constant in Java is placed in a constant pool, and when the String.intern () method runs, it checks to see if the constant pool has an object that is equal to this string, and if there is a reference to the object in the constant pool that does not exist, first add the string to the constant pool. It then returns a reference to the string. Then the String.intern method can be used to simulate the overflow of the running constant area.
4. Thread Stacks
stack (JVM stack) storage is primarily a place for stack frames (local variable tables, operand stacks, dynamic links, method exit information). Note the stack and stack frames: stack frames are included.
There are two memory exceptions associated with thread stacks:
Stackoverflowerror (method call hierarchy too deep, insufficient memory to create new stack frame)
OutOfMemoryError (Too many threads, not enough memory to create a new thread)
1). java.lang.StackOverflowError
Stack overflow throws a java.lang.StackOverflowError error, this occurs because when the method is running, when a new stack frame is requested, the stack remains less than the space required for the battle frame.
For example, by recursively calling the method, the stack frame is constantly generated and the stack space is piled up until an exception is thrown:
?
123456789101112 |
package
com.demo3;
public
class
OOMTest {
public
void
stackOverFlowMethod() {
stackOverFlowMethod();
}
public
static void
main(String... args) {
OOMTest oom =
new
OOMTest();
oom.stackOverFlowMethod();
}
}
|
Operation Result:
?
12345678910 |
Exception in thread
"main" java.lang.StackOverflowError
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
at com.demo3.OOMTest.stackOverFlowMethod(OOMTest.java:
5
)
.....
|
2). Java.lang.OutOfMemoryError:unable to create new native thread
Because the virtual opportunity provides some parameters to ensure the allocation of the heap and the method area, the rest of the memory is basically owned by the stack, and each thread has its own separate stack space (heap, the method area is common to the thread). So:
If you increase the virtual machine parameter XSS, each thread occupies a larger stack space, then the number of threads that can be established must be reduced
Formula: Line stacks total available memory =JVM total memory-(value of-XMX)-(value of-xx:maxpermsize)-memory occupied by program counters
If the-xmx or-xx:maxpermsize is too large, the smaller the space available to the thread stack, the smaller the number of threads that can be created if the stack capacity of the-XSS parameter configuration is constant.
Both of these situations result in the java.lang.OutOfMemoryError:unable to create new native thread exception thrown when the number of threads created is too long and the stack memory is not enough to create a fresh thread.
PS: Because Java threads are insinuate to the operating system's kernel thread in the Windows platform virtual machine, running the code that generates the exception can cause the operating system to feign death.
Java Common Memory Overflow exception analysis (OUTOFMEMORYERROR)