首先里面存了什么?
类型信息,常量,静态变量,即时编译后的代码缓存。
常量嘛,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(); } }