java.lang.OutOfMemoryError: PermGen space: java reflection

简介: 原文地址:https://stackoverflow.com/questions/16130292/java-lang-outofmemoryerror-permgen-space-java-reflection/47090043#47090043问题使用如下java反射代码:Method method = LogFactory.

原文地址:https://stackoverflow.com/questions/16130292/java-lang-outofmemoryerror-permgen-space-java-reflection/47090043#47090043

问题

使用如下java反射代码:

Method method = LogFactory.class.getDeclaredMethod("getContextClassLoader");
method.setAccessible(true);
ClassLoader classLoader = (ClassLoader)method.invoke(null);
LogFactory.release(classLoader);

使用jprofiler看到很多类似sun.reflect.GeneratedMethodAccessor11这种类,在每次调用的时候都增长:

sun.reflect.BootstrapConstructorAccessorImpl
sun.reflect.NativeConstructorAccessorImpl
sun.reflect.DelegatingConstructorAccessorImpl
sun.reflect.DelegatingClassLoader

我觉得这个是PermGen space 增长的原因,但是如何清理掉这些类呢?

网友[路人甲]的一段解释

当使用java反射,有两种方法获取被反射的类的信息。可以使用JNI的方式,也可以使用字节码的方式。如果使用字节码的方式,需要java的类和类加载器(sun/reflect/GeneratedMethodAccessor class and sun/reflect/DelegatingClassLoader)。这些类和类加载器使用本地内存。使用字节码的方式也使用JIT编译,但是这会更加重本地内存的使用。如果频繁使用java反射,这更能带来一个显著的内存使用上的上升。JVM会优先使用JNI的方式,在经历过一些相同的类之后,才会使用字节码的方式。这被称为膨胀效应-当JVM从JNI方式变为字节码的方式。幸运的是,我们可以通过一个Java属性配置,sun.reflect.inflationThreshold属性告诉JVM使用JNI方式多少次,如果设置为0,JNI方式将会被一直使用。既然字节码的方式比JNI的方式使用更多内存,如果我们使用Java反射,我们系王世勇JNI的方式。为了实现这个,我们只需要设置inflationThreshold属性为0即可。

网友[路人乙]的补充

如果使用oracle 的JVM,这样子设置:

sun.reflect.inflationThreshold=2147483647 

如果使用IBM JVM,这样设置:

-Dsun.reflect.inflationThreshold=0
目录
相关文章
|
6月前
|
Java Linux
8 种 Java- 内存溢出六 -Out of swap space?
8 种 Java- 内存溢出六 -Out of swap space?
|
7天前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
6月前
|
安全 Java API
Java反射(Reflection)的技术性文章
Java反射(Reflection)的技术性文章
41 1
|
4月前
|
存储 Java 程序员
Java面试题:请解释Java中的永久代(PermGen)和元空间(Metaspace)的区别
Java面试题:请解释Java中的永久代(PermGen)和元空间(Metaspace)的区别
208 11
|
4月前
|
Java 关系型数据库 数据库
实时计算 Flink版操作报错合集之拉取全量数据时,如何解决Checkpoint失败并且报错为 "java.lang.OutOfMemoryError: Java heap space"
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
4月前
|
监控 Java
【Java】已解决:Java.lang.OutOfMemoryError: GC overhead limit exceeded
【Java】已解决:Java.lang.OutOfMemoryError: GC overhead limit exceeded
104 0
|
6月前
|
Java
什么是Java中的反射(Reflection),如何使用它
什么是Java中的反射(Reflection),如何使用它
|
6月前
|
存储 Java 关系型数据库
8 种 Java- 内存溢出之三 -Permgen space
8 种 Java- 内存溢出之三 -Permgen space
|
6月前
|
缓存 Java
8 种 Java 内存溢出之一:Java Heap Space
8 种 Java 内存溢出之一:Java Heap Space
|
8天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?