The figure above is the main data area of the jvm virtual machine when it runs. The blue part is the thread sharing area, and the white part is the thread private area.
The following examples all run in jdk1.7
1. Heap memory overflow
/**
* VM Args: -Xms2m -Xmx2m
* Created by Stay on 2017/5/15 14:50.
*/
public class Base1 {
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
while(true){
list.add(new byte[2 * 1024]);
}
}
}
result: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
-Xms2m heap memory minimum 2m
-Xmx2m heap memory is up to 2m, parameter settings are the same to avoid automatic heap expansion
We add -XX:+PrintGCDetails to print out the GC recycling process:
[GC [PSYoungGen: 2047K->504K(2560K)] 2047K->2028K(5120K), 0.0014692 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 504K->0K(2560K)] [ParOldGen: 1524K->1696K(5120K)] 2028K->1696K(7680K) [PSPermGen: 2776K->2775K(21504K)], 0.0123204 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[GC [PSYoungGen: 2046K->512K(2560K)] 3743K->4080K(7680K), 0.0009728 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 512K->0K(2560K)] [ParOldGen: 3568K->3587K(5120K)] 4080K->3587K(7680K) [PSPermGen: 2792K->2792K(21504K)], 0.0063521 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 2047K->503K(2560K)] [ParOldGen: 3587K->5066K(5120K)] 5635K->5570K(7680K) [PSPermGen: 2815K->2815K(21504K)], 0.0091229 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 2046K->2023K(2560K)] [ParOldGen: 5066K->5056K(5120K)] 7113K->7079K(7680K) [PSPermGen: 2843K->2843K(21504K)], 0.0054760 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 2046K->2046K(2560K)] [ParOldGen: 5056K->5056K(5120K)] 7102K->7102K(7680K) [PSPermGen: 2843K->2843K(21504K)], 0.0056718 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 2048K->2046K(2560K)] [ParOldGen: 5118K->5118K(5120K)] 7166K->7164K(7680K) [PSPermGen: 2845K->2845K(21504K)], 0.0051912 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 2046K->2046K(2560K)] [ParOldGen: 5118K->5106K(5120K)] 7164K->7153K(7680K) [PSPermGen: 2845K->2845K(21504K)], 0.0075618 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 2046K->2046K(2560K)] [ParOldGen: 5119K->5119K(5120K)] 7165K->7165K(7680K) [PSPermGen: 2846K->2846K(21504K)], 0.0056501 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 2046K->2046K(2560K)] [ParOldGen: 5119K->5119K(5120K)] 7165K->7165K(7680K) [PSPermGen: 2846K->2846K(21504K)], 0.0051502 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GCException in thread "main" [PSYoungGen: 2048K->0K(2560K)] [ParOldGen: 5119K->518K(4608K)] 7167K->518K(7168K) [PSPermGen: 2872K->2872K(21504K)], 0.0084184 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
java.lang.OutOfMemoryError: Java heap space
at jvm.base1.main(base1.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Heap
PSYoungGen total 2560K, used 67K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
eden space 2048K, 3% used [0x00000000ffd00000,0x00000000ffd10c38,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
to space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
ParOldGen total 4608K, used 518K [0x00000000ff800000, 0x00000000ffc80000, 0x00000000ffd00000)
object space 4608K, 11% used [0x00000000ff800000,0x00000000ff8819e0,0x00000000ffc80000)
PSPermGen total 21504K, used 2897K [0x00000000fa600000, 0x00000000fbb00000, 0x00000000ff800000)
object space 21504K, 13% used [0x00000000fa600000,0x00000000fa8d4468,0x00000000fbb00000)
As you can see from the printed information, the JVM is trying to recycle, but it can't resist the power of while(true).
2. Stack Overflow
/**
* VM Args: -Xss128k
* Created by Stay on 2017/5/15 15:41.
*/
public class Base2 {
private int stackLength = 1;
public static void main(String[] args) {
Base2 base2 = null;
try {
base2 = new Base2();
base2.stackLeak();
} catch (Throwable e) {
System.out.println("stack length:" + base2.stackLength);
throw e;
}
}
public void stackLeak() {
stackLength++;
stackLeak();
}
}
result:
Exception in thread "main" java.lang.StackOverflowError
stack length:11409
.....
Thread api has an unusual constructor, Thread (ThreadGroup, Runnable target, String name, long stackSize), and the last parameter is the stack size setting for each thread
Another chestnut:
/**
* Created by Stay on 2017/5/15 16:15.
*/
public class Base3 {
private static int count = 1;
public static void main(String[] args) {
Thread t1 = new Thread(null,new Runnable() {
@Override
public void run() {
try {
add(1);
} catch (Throwable e) {
System.out.println(count);
e.printStackTrace();
}
}
private void add(int i) {
count++;
add(i + 1);
}
},"stackTest");
t1.start();
}
}
result:
java.lang.StackOverflowError
10472
....
At the end, add a stackSize parameter, Thread T1 = new Thread (null,...,'stackTest', 1 << 24);
result:
975998
java.lang.StackOverflowError
....
The final value of count is much larger than it was at first because we allocated more stack space to each thread, but the number of threads we could create was smaller because the total stack space did not change.This construction method is rarely used in general.
Sometimes we just divide the jvm into two stacks and stacks, which is a fairly rough division. It only shows that most programmers are most concerned about these two areas. The stack referred to here is the virtual machine stack, or the local variable table part of the virtual machine.
The stack is where object instances are stored, and all new instances are stored in the stack referencing only the objects in the stack.The garbage collector also manages this area primarily, called the GC heap
3. Method Area Memory Overflow (PermGen space)
We experimented with the intern() method of strings
To overflow as quickly as possible, the jvm parameter sets the permanent generation parameter 5M:-XX:PermSize=5m-XX:MaxPermSize=5m
public static void main(String[] args) {
List list = new ArrayList();
int i = 0;
while(true){
list.add((String.valueOf(i++)).intern());
}
}
The results are as follows: PermGen space is prompted after OutOfMemoryError; changing the code to jdk6 and below can report the following exceptions. The reason why jdk7 high version and above jvm has gradually started canceling the permanent generation is that only heap memory exceptions will be reported
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at com.TestSocket.main(TestSocket.java:12)