美文网首页
实验: metaspace区域OOM

实验: metaspace区域OOM

作者: holysu | 来源:发表于2021-04-06 00:24 被阅读0次

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 MetaspaceOOMCar$$EnhancerByCGLibxxx image

cglib 总共动态生成了 668个类


image

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


image

相关文章

  • 实验: metaspace区域OOM

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

  • OOM之Metaspace

    JVM参数-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8mJava 8及之...

  • Metaspace OOM问题处理

    一、背景 系统会偶现下面Metaspace区OOM的情况,服务器在重启后就会立马恢复,而且后面基本不会再复现,可能...

  • Java Metaspace OOM问题分析

    问题描述: 系统上线发生FullGC 定位过程: 1、查看zabbix监控找到FullGC时间点;2、根据时间点搜...

  • 生产问题-MetaSpace空间OOM

    发现故障、 生产服务器某天开始,突然每天不同时间点报MetaSpace的oom,因为本身服务器没有监控,加上是集群...

  • Netty模拟OOM-Metaspace

    在模拟OOM之前, 先简单说下Netty服务端向客户端发送数据的时候, 涉及两个存储数据的地方, 如下图所示 业务...

  • OOM问题排查方法

    根据日志确定发生OOM的原因和区域,以下几个内存区域都可能发生OOM,先找到打印出的OOM错误日志和dump文件(...

  • 关于 MetaSpace 及 FastJSON 导致的 OOM

    关于 MetaSpace 内存 在 JDK8 之前,虚拟机内存主要分为堆和非堆两部分,堆中划分新生代老生代,非堆中...

  • 常见OOM问题之metaspace space元空间OOM问题详

    本文来自于HeapDump性能社区![https://heapdump.cn/] !有性能问题,上HeapDump...

  • Java问题记录

    java.lang.OutOfMemoryError: Metaspace Metaspace 的空间与java代...

网友评论

      本文标题:实验: metaspace区域OOM

      本文链接:https://www.haomeiwen.com/subject/xzbdkltx.html