永久代或者元空间溢出模拟

首先里面存了什么?

类型信息,常量,静态变量,即时编译后的代码缓存。

常量嘛,String.intern(),JDK6及之前可以,但是JDK7起就将字符串常量池,静态变量移入堆中了。

类型信息,即时代码缓存,基本一对一的东西。

在JDK7后,用户能动的也就它了。那只要能无限增加类型信息就行了呗。

问题简化为在运行期不断创建新的类型信息,不断加载。

cglib就可以在运行期动态创建类。

cglib默认开启了UserCache生成的代理类都会复用原先产生在缓存中的类,所以至始至终都只有一个代理类,所以不会产生内存溢出。手动关闭它,代码如下

笔者是JDK8配置-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m。 JDK6的配置自行查询

public class RealService { public void realMethod() { System.out.println("realMethod execute"); } public static void main(String[] args) { //设置代理类生成目录 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/wangzhigang/temp"); Enhancer enhancer = new Enhancer(); enhancer.setUseCache(false); //设置超类,因为cglib基于父类 生成代理子类 enhancer.setSuperclass(RealService.class); //设置回调,也就是我们的拦截处理 enhancer.setCallback(new MyServiceInterceptor()); //创建代理类 RealService realService = (RealService) enhancer.create(); for (int i = 0; i < 1000; i++) { System.out.println(i); realService = (RealService) enhancer.create(); } //代用代理类的方法 realService.realMethod(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygfzg.html