JAVA内存学习1——玩一玩*Error和OutOfMemoryError

最近开始看周志明老师的《深入理解JAVA虚拟机》,只看不写不是好程序员,故记下一些心得和代码,作为留念。

第二章自动内存管理机制 P40

看到书中有提到*Error和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 get*Error(){
        for(;;){
            get*Error();
        }
    }

获得后发现,get*Error 打印出错误日志为:

Exception in thread "main" java.lang.*Error
at com.play.test.jvm.memory.GetError.get*Error(GetError.java:30)

...

at com.play.test.jvm.memory.GetError.get*Error(GetError.java:30)

正好是1024个get*Error ,也就是递归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区。



上一篇:阿里云ACK服务使用Windows容器挂载NAS SMB最佳实践


下一篇:MySQL InnoDB中的锁-间隙锁(Gap Lock)