常量池导致溢出(结合不同jdk版本,会有不一样的异常情况)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| import java.util.ArrayList;
import java.util.List;
public class StringOomMock {
static String base = "string";
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i=0;i< Integer.MAX_VALUE;i++){
String str = base + base;
base = str;
list.add(str.intern());
}
}
}
|
可以得出结论:
JDK 1.6下,会出现“PermGen Space”的内存溢出,
而在 JDK 1.7和 JDK 1.8 中,会出现堆内存溢出,
并且 JDK 1.8中 PermSize 和 MaxPermGen 已经无效。
因此,可以大致验证 JDK 1.7 和 1.8 将字符串常量由永久代转移到堆中,并且 JDK 1.8 中已经不存在永久代的结论。
栈溢出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| public class StackErrorMock {
private static int index = 1;
public void call(){
index++;
call();
}
public static void main(String[] args) {
StackErrorMock mock = new StackErrorMock();
try {
mock.call();
}catch (Throwable e){
System.out.println("Stack deep : "+index);
e.printStackTrace();
}
}
}
|
堆溢出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| import java.util.ArrayList;
import java.util.List;
public class HeapOomMock {
public static void main(String[] args) {
List<byte[]> list = new ArrayList<byte[]>();
int i = 0;
boolean flag = true;
while (flag){
try {
i++;
list.add(new byte[1024 * 1024]);//每次增加一个1M大小的数组对象
}catch (Throwable e){
e.printStackTrace();
flag = false;
System.out.println("count="+i);//记录运行的次数
}
}
}
}
|