为了账号安全,请及时绑定邮箱和手机立即绑定

【备战春招】第2天+模拟内存溢出

标签:
Java

课程名称:Java生产环境下性能监控与调优详解

课程章节:第二章

主讲老师:若鱼1919

课程内容:

  1. 模拟堆内存溢出,还有栈内存溢出

    1. -XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M   非堆

    2. -Xmx32M -Xms32M   堆

  2. //controller类
    @RestController
    public class MemoryController {
    //这个实体类随便搞就可以了,只是要达到堆内存溢出的效果
       private List<User> userList = new ArrayList<>();
       //达到栈内存溢出的效果需要创建类,所以需要有一个创建类的程序,后续带了
       private List<Class<?>> classList = new ArrayList<>();

       @GetMapping("/heap")
       public String heap(){
           int i = 0;
           while (true){
               userList.add(new User(i++, UUID.randomUUID().toString()));
           }
       }

       @GetMapping("/nonHeap")
       public String nonHeap(){
           int i = 0;
           while (true){
               classList.addAll(Metaspace.createClasses());
           }
       }
    }
    //创建类对象的类
    public class Metaspace extends ClassLoader {

       public static List<Class<?>> createClasses() {
           // 类持有
           List<Class<?>> classes = new ArrayList<Class<?>>();
           // 循环1000w次生成1000w个不同的类。
           for (int i = 0; i < 10000000; ++i) {
               ClassWriter cw = new ClassWriter(0);
               // 定义一个类名称为Class{i},它的访问域为public,父类为java.lang.Object,不实现任何接口
               cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null,
                       "java/lang/Object", null);
               // 定义构造函数<init>方法
               MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
                       "()V", null, null);
               // 第一个指令为加载this
               mw.visitVarInsn(Opcodes.ALOAD, 0);
               // 第二个指令为调用父类Object的构造函数
               mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
                       "<init>", "()V");
               // 第三条指令为return
               mw.visitInsn(Opcodes.RETURN);
               mw.visitMaxs(1, 1);
               mw.visitEnd();
               Metaspace test = new Metaspace();
               byte[] code = cw.toByteArray();
               // 定义类
               Class<?> exampleClass = test.defineClass("Class" + i, code, 0, code.length);
               classes.add(exampleClass);
           }
           return classes;
       }
    }


课程收获:

之前老是遇到内存溢出,其实内存溢出也是分栈内存溢出和堆内存溢出的,不过这次真的是自己动手实现了。

Exception in thread "http-nio-8080-exec-2" java.lang.OutOfMemoryError: Metaspace  栈内存溢出

Exception in thread "RMI TCP Connection(idle)" java.lang.OutOfMemoryError: GC overhead limit exceeded:堆内存溢出

这个创建class的类其实没太懂,我还要再听一遍

https://img3.sycdn.imooc.com/63e0c47c00011b8d16461181.jpg


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
6
获赞与收藏
5

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消