JVM内存分区再熟悉

1.string.intern
从常量池返回字符串常量或将字符串常量放入常量池中

2.JVM内存分区
虚拟机栈(栈大小/栈深度)、程序计数器、方法区、堆(分代)

3.编写内存泄露代码
vm options:-Xms10M -Xmx10M -Xmn5M -verbose:gc -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m  -XX:+HeapDumpOnOutOfMemoryError

public class TestLeak {
    private static final int _1MB = 2*1024*1024;
    public static void main(String[] args) {
        System.out.println("start");
        int i =0;
        while (true) {
            System.out.println(i++);
            ObjectA objectA = new ObjectA();
            ObjectB objectB = new ObjectB();
            objectA.objectB = objectB;
            objectB.objectA = objectA;
        }
    }

    static class ObjectA {
        ObjectB objectB;
        byte[] allocation1 = new byte[2 * _1MB];
    }

    static class ObjectB {
        ObjectA objectA;
        byte[] allocation1 = new byte[2 * _1MB];
    }

}


4.编写代码测试Metaspace和永久代溢出验证
永久代是对虚拟机规范方法区的实现,只是作为堆的逻辑部分,目的是为了避免单独编写内存管理代码
jdk 1.6中需要设置permspace maxpermspace来限制永久代(或方法区)内存大小
jdk 1.7中开始将字符串常量迁移出永久代(或方法区),具体是迁移到堆中,使用string.intern()可以验证?
jdk 1.8中已经彻底移除永久代?用metaspace替换,metaspace直接从本地内存分配,也需要通过MetaspaceSize或MaxMetaspaceSize来限制大小
针对字符串常量的测验
在jdk 1.6中,报错Perm space OOM
在jdk 1.7中,报错Heap space OOM
在jdk 1.8中,报错Heap space OOM(不同版本表现不一样?字符串常量可能还在堆中分配?)
在jdk 1.8中,使用Cglib产生大量动态类,限制MetaspaceSize大小,可以报错Metaspace OOM

5.使用Eclipse MAT插件
查看各个线程以及线程中的对象个数、占用内存情况
查看占用内存多的大对象排行
辅助进行Memory Leak分析

 

你可能感兴趣的:(理解Java虚拟机)