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


    首先里面存了什么?

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

    常量嘛,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();
        }
    }
    public class MyServiceInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("before exexute");
            Object result=methodProxy.invokeSuper(obj, objects);
            System.out.println("after exexute");
            return result;
        }
    }
    523
    524
    525
    526
    Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
        at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:345)
        at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:492)
        at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:114)
        at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291)
        at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:480)
        at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:305)
        at com.hhdd.controller.book2.RealService.main(RealService.java:63)
    Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:459)
        at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:336)
        ... 6 more
    Caused by: java.lang.OutOfMemoryError: Metaspace
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        ... 11 more
  • 相关阅读:
    UNIX 环境模拟工具Cygwin安装及使用图文教程
    转转转!SpringMVC访问静态资源的三种方式
    转!!!解释Eclipse下Tomcat项目部署路径问题(.metadata.pluginsorg.eclipse.wst.server.core mp0wtpwebapps)
    JavaWeb中读取文件资源的路径问题 -- 转自新浪博客
    springMVC学习(10)-上传图片
    springMVC学习(9)-全局异常处理
    springMVC学习(8)-数据回显
    springMVC学习(7)-springMVC校验
    springMVC学习(6)-包装pojo类型、数组、list、Map类型参数绑定
    springMVC学习(5)-参数绑定
  • 原文地址:https://www.cnblogs.com/aoeiuv/p/14686189.html
Copyright © 2020-2023  润新知