JVM学习 内存溢出测试

兄弟们一定谨慎测试,小心你的电脑的jdk崩掉。接下来就直接将测试代码放在下面,接着上一个文章的描述测试各种内存溢出导致的区域性问题,具体的解释在代码注释中可以查看。

1、heap堆内存溢出

public class heap {
/*堆内存爆出的溢出异常测试,一般8以后的JDK不会产生类似问题,其实只需要不断创造实力对象就可以!原因是单个对象的内存太小*/
    static class heap1{
    }

    public static void main(String[] args) {
        ArrayList<heap1> arrayList = new ArrayList<>();
        while(true){
            /*不断地向数组列表里添加新对象,直至堆内存溢出*/
            arrayList.add(new heap1());
        }
    }
}

2、方法区的字符串常量池内存溢出

public class permGen {
    /*测试方法区内存溢出*/
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        short i = 0;
        while(true){
            /*intern方法返回的位置在字符串常量池中的引用上,在虚拟机对堆的分区来讲,他应该属于老年代区*/
            set.add(String.valueOf(i++).intern());
        }
    }
}

3、虚拟机栈内存扩展异常

public class SEfM {
    /*虚拟机栈的内存溢出,只需要实现方法的互调就能达到*/
    private int dosLength=0;
    public void dos(){
        dosLength++;
        dos();
    }

    public static void main(String[] args) {
        SEfM sEfM = new SEfM();
        try {
            sEfM.dos();
        }catch (StackOverflowError error){
            System.out.println("此时虚拟机栈局部变量表的一个slot槽大小约为:"+sEfM.dosLength);
            throw error;
        }
    }
}

4、本地方法栈栈帧内扩展异常

public class SEfM1 {
    /*本地方法栈的内存溢出测试,主要运用定义变量的方法使本地方法栈的单个栈帧内存溢出*/
    private static int stackLength = 0;

    public static void test() {
        long user1, user2, user3;
        stackLength++;
        test();
        user1 = user2 = user3 = 0;
    }

    public static void main(String[] args) {
        try {
            test();
        }catch (StackOverflowError error){
            System.out.println("此时本地方法栈的单个栈帧大小约为:"+stackLength);
            throw error;
        }
    }
}

5、多线程宕机(堆内存溢出或是虚拟机栈内存扩展异常)

public class SEfM1 {
    /*本地方法栈的内存溢出测试,主要运用定义变量的方法使本地方法栈的单个栈帧内存溢出*/
    private static int stackLength = 0;

    public static void test() {
        long user1, user2, user3;
        stackLength++;
        test();
        user1 = user2 = user3 = 0;
    }

    public static void main(String[] args) {
        try {
            test();
        }catch (StackOverflowError error){
            System.out.println("此时本地方法栈的单个栈帧大小约为:"+stackLength);
            throw error;
        }
    }
}

6、Enhaner生成器代理导致的方法区内存溢出(详见AOP底层原理那一文章对于cglib动态代理的相关解释)

public class cglib {
/*采用不断创建动态代理增强生成器来占用,由于方法区中存储的是静态变量,常量,字面量,类的类型信息,字节码文件的代码等
* 其中我们的代理增强器会在被增强类的方法中添加增强的信息,所以方法区会不断的增加内存的使用,从而实现方法区的内存溢出*/
    public static void main(String[] args) {
        while (true){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(active.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
                throws Throwable {
                   return methodProxy.invokeSuper(objects,args);
                }
            });
            enhancer.create();
        }
    }
    static class active{
    }
}

7、测试String:intern();方法返回引用的位置

public class intern {
    public static void main(String[] args) {
/*测试string:intern();返回的引用是否在字符串常量池且这个常量池已经转移到java堆中,如果一致返回true*/
        String str1 = new StringBuilder("计算机").append("软件").toString();
        System.out.println(str1);
        System.out.println(str1.intern()==str1);

        String str2 = new StringBuilder("sta").append("tic").toString();
        System.out.println(str2.intern()==str2);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ForestSpringH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值