zoukankan      html  css  js  c++  java
  • 实验: metaspace区域OOM

    Cglib 动态代理,会动态创建类 如果使用不当会导致生成大量的类元数据 塞满metaspace

    试验代码

    依赖包

      <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.3.0</version>
      </dependency>
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * 模拟元数据区被塞满导致oom
     *
     * @author holysu 2020/8/11
     */
    public class MetaspaceOOM {
    
        /**
         -XX:+UseParNewGC
         -XX:+UseConcMarkSweepGC
         -XX:MetaspaceSize=10M
         -XX:MaxMetaspaceSize=10M
         -XX:+PrintGCDetails
         -Xloggc:gc.log
         -XX:+HeapDumpOnOutOfMemoryError
         -XX:HeapDumpPath=./
         * @param args
         */
        public static void main(String[] args) {
            int counter = 0;
            while (true) {
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(Car.class);
                enhancer.setUseCache(false);
                enhancer.setCallback(new MethodInterceptor() {
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        if (method.getName().equals("run")) {
                            System.out.println("running, enhanced");
                            return methodProxy.invokeSuper(o, objects);
                        } else {
                            return methodProxy.invokeSuper(o, objects);
                        }
                    }
                });
    
                Car car = (Car) enhancer.create();
                car.run();
    
                System.out.println("目前创建了 " + (counter++) + " 个Car的动态子类");
            }
        }
    
        static class Car {
            public void run() {
                System.out.println("running...");
            }
        }
    }
    
    

    异常信息

    执行报错
    java.lang.OutOfMemoryError: Metaspace
    Dumping heap to ./java_pid13748.hprof ...
    Heap dump file created [2923143 bytes in 0.037 secs]
    Exception in thread "main" net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:348)
    at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:117)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
    at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480)
    at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:305)
    at MetaspaceOOM.main(MetaspaceOOM.java:42)
    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 net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:459)
    at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
    ... 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

    gc日志

    4.669: [GC (Allocation Failure) 4.669: [ParNew: 34944K->2104K(39296K), 0.0033046 secs] 34944K->2104K(126720K), 0.0035844 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    5.218: [GC (Allocation Failure) 5.218: [ParNew: 37048K->2256K(39296K), 0.0051226 secs] 37048K->2256K(126720K), 0.0053311 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
    5.633: [GC (Allocation Failure) 5.633: [ParNew: 37200K->2664K(39296K), 0.0101116 secs] 37200K->2664K(126720K), 0.0102989 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

    Gc日志还是比较清晰的打印出 Metadata 到达阈值引起的fullgc
    5.973: [Full GC (Metadata GC Threshold)5.973: [CMS: 0K->2302K(87424K), 0.0538876 secs] 28792K->2302K(126720K), [Metaspace: 9186K->9186K(1058816K)], 0.0543441 secs] [Times: user=0.08 sys=0.03, real=0.06 secs]
    6.027: [Full GC (Last ditch collection) 6.027: [CMS: 2302K->1410K(87424K), 0.0168118 secs] 2302K->1410K(126848K), [Metaspace: 9186K->9186K(1058816K)], 0.0169643 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]
    6.046: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1410K(87424K)] 1410K(126848K), 0.0003738 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    6.046: [CMS-concurrent-mark-start]
    6.089: [CMS-concurrent-mark: 0.014/0.043 secs] [Times: user=0.06 sys=0.00, real=0.04 secs]
    6.089: [CMS-concurrent-preclean-start]
    6.091: [CMS-concurrent-preclean: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    6.091: [GC (CMS Final Remark) [YG occupancy: 687 K (39424 K)]6.091: [Rescan (parallel) , 0.0003632 secs]6.091: [weak refs processing, 0.0001684 secs]6.091: [class unloading, 0.0022085 secs]6.094: [scrub symbol table, 0.0013801 secs]6.095: [scrub string table, 0.0003217 secs][1 CMS-remark: 1410K(87424K)] 2097K(126848K), 0.0048304 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
    6.096: [CMS-concurrent-sweep-start]
    6.096: [CMS-concurrent-sweep: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    6.097: [CMS-concurrent-reset-start]
    6.099: [CMS-concurrent-reset: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    Heap
    par new generation total 39424K, used 1038K [0x0000000081200000, 0x0000000083cc0000, 0x0000000095ec0000)
    eden space 35072K, 2% used [0x0000000081200000, 0x0000000081303890, 0x0000000083440000)
    from space 4352K, 0% used [0x0000000083440000, 0x0000000083440000, 0x0000000083880000)
    to space 4352K, 0% used [0x0000000083880000, 0x0000000083880000, 0x0000000083cc0000)
    concurrent mark-sweep generation total 87424K, used 1410K [0x0000000095ec0000, 0x000000009b420000, 0x0000000100000000)
    Metaspace used 9214K, capacity 10134K, committed 10240K, reserved 1058816K
    class space used 790K, capacity 841K, committed 896K, reserved 1048576K

    到底是什么东西在元数据?

    通过mat分析oom时候自动dump的文件

    首先发现应用程序类加载器 AppClassLoader 加载了很多东西
    image发现有大量 CGLib 相关的类以及 生成的Car类 class MetaspaceOOM(Car)(EnhancerByCGLib)xxx

    image

    cglib 总共动态生成了 668个类
    image list outgoing objects 进去看,这个名字怪怪的类 父类是 Car, 关联了一堆 cglib的代理对象 也就是说肯定是通过cglib加强 car 的时候有问题
    image

    本文来自博客园,作者:mushishi,转载请注明原文链接:https://www.cnblogs.com/mushishi/p/14553136.html

  • 相关阅读:
    struct page*
    ARM平台linux内核Notes 1
    CTDIY1字符设备驱动的使用
    深入理解linux内核读书笔记1
    在linux下设置pl2303串口
    struct per_cpu_pageset
    ARM平台linux内核Notes 2
    CTDIY2字符设备驱动的注册
    深入理解linux内核读书笔记2
    How to rollback a transaction in TSQL
  • 原文地址:https://www.cnblogs.com/mushishi/p/14553136.html
Copyright © 2011-2022 走看看