24.jvm内存结构部分——方法区_内存溢出2

上文向大家演示了方法区的内存溢出

1.8以前演示了永久代可能会产生一个溢出。
1.8以后演示了元空间也有可能产生的一个溢出。


那么有同学会说,你这个两种情况都是我们自己循环了好多次,产生了一大堆class 啊,加载了一些class,导致了内存溢出。

那实际开发中我不会那么傻,我没事产生那么多class 干嘛呢?

你还真别说,那实际场景里我们动态产生class 并加载这些类的场景是非常非常多的。

 

举几个例子,比如说大家都学过,都用过我们的spring 框架,mybatis 框架等等。
那么这些框架里面他们都用了一些字节码技术。就比如说我们的spring 和mybatis 啊,他们都会用到cglib这样一个技术。
还记得吧?
spring 用它生成一些代理类,这些代理类呢是spring 中aop的一个核心,那么mybatis里面呢也用到了cglib,可以用cglib去产生mapper 接口的那个实现类。
这些都是它们用的cglib,cglib它的底层实际是什么呢?我们来看一下。

上文演示了这个例子中,我们用到了ClassWriter,ClassWriter我们看一下它的继承关系

它继承自一个叫ClassVisitor类,当然这个包呢由于sun/oracle公司把这个ClassWriter和ClassVisitor导入到jdk以后,他就把这个包名换了,我们看不出来原始的这个包名。
实际上它是这个叫org objectweb asm 这个项目中提供的这些ClassWriter类完成动态生成这个类的二进制字节码。

那我们不妨看一下cglib又是怎么做的。

 

 它也有asm,这里面也有我们的这个叫ClassWriter,它也是一脉相承的集成,一个叫class visitor。当然这些包名也做了一些修改,其实他们都系出同源,是同一个东西。
也就是上文给大家演示的这个ClassWriter和cglib中的ClassWriter它们的功能都是类似的,
都是在运行期间动态生成类似字节码,完成动态的类加载,

我们的代理技术广泛应用这种字节码的动态生成技术。
所以实际情况中,我们用这种spring, mybatis 的时候,经常会产生大量的
在运行期间生成的类,其实还是很容易导致永久性的内存溢出的。

当然到了1.8以后,由于元空间使用的是系统内存相对充裕了很多,并且它的垃圾回收机制也是由元空间自行来管理的。就不会像永久代一样,垃圾回收效率非常的低,经常会由于回收效率低,导致我们的内存溢出。


后面呢我们讲到了垃圾回收时,还会对比永久代和元空间。
它们在这个垃圾回收上的一个区别。

现在大家要了解是我们的实际场景的话,这种动态加载类动态生成类的场景是非常多的,
使用不当都会导致这种方法区的内存溢出。所以大家不要轻视它。遇到这种问题,
我们要看看是不是你的框架使用的不合理,导致产生了太多的这个新的类型。

上一篇:23.jvm内存结构部分——方法区_内存溢出1_tgbyhn31的博客-CSDN博客

下一篇:25.jvm内存结构部分——方法区_常量池_tgbyhn31的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值