最近开始看周志明老师的《深入理解JAVA虚拟机》,只看不写不是好程序员,故记下一些心得和代码,作为留念。
第二章自动内存管理机制 P40
看到书中有提到StackOverFlowError和OutOfMemoryError,弄出来玩一玩。
static void getOutOfMemoryError(){
List<int[]> list = new LinkedList<int[]>();
for(int i=0;i<1000;i++){
System.out.println(i);
int[] tmp=new int[1000000];
list.add(tmp);
}
}
static void getStackOverFlowError(){
for(;;){
getStackOverFlowError();
}
}
获得后发现,getStackOverFlowError 打印出错误日志为:
Exception in thread "main" java.lang.StackOverflowError
at com.play.test.jvm.memory.GetError.getStackOverFlowError(GetError.java:30)
...
at com.play.test.jvm.memory.GetError.getStackOverFlowError(GetError.java:30)
正好是1024个getStackOverFlowError ,也就是递归1024次自动抛出了ERROR
而getOutOfMemoryError
在循环执行到第230次的时候开始报错(230-232),此时list中应该有2.3*10^8个int,我是用的64位的JVM,故int占4B,
所以总内存占用大概是:9.2*10^9B, 也就是920M,我的内存设置为-Xms128m -Xmx1024m 最大1G,还有接近100M内存去哪了呢?
改进方法,直接打出当前占用内存值
static void getOutOfMemoryError(){
List<int[]> list = new LinkedList<int[]>();
for(int i=0;i<1000;i++){
System.out.println(i);
if(i>229){
Runtime run = Runtime.getRuntime();
System.out.println( run.maxMemory());
System.out.println( run.totalMemory());
System.out.println( run.freeMemory());
}
int[] tmp=new int[1000000];
list.add(tmp);
}
}
输出结果
232
当前JVM最大可用内存:954728448
当前JVM使用内存总量:940572672
当前剩余可用内存:11769904
总可用内存为955M左右,还有69M内存去哪了?
初步推测为虚拟机占用,分区应该是perm区。