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
目录
相关文章
|
7月前
|
Java Linux
8 种 Java- 内存溢出六 -Out of swap space?
8 种 Java- 内存溢出六 -Out of swap space?
|
1月前
|
分布式计算 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 若是设置参数该如何设置
|
7月前
|
安全 Java API
Java反射(Reflection)的技术性文章
Java反射(Reflection)的技术性文章
49 1
|
5月前
|
存储 Java 程序员
Java面试题:请解释Java中的永久代(PermGen)和元空间(Metaspace)的区别
Java面试题:请解释Java中的永久代(PermGen)和元空间(Metaspace)的区别
242 11
|
5月前
|
Java 关系型数据库 数据库
实时计算 Flink版操作报错合集之拉取全量数据时,如何解决Checkpoint失败并且报错为 "java.lang.OutOfMemoryError: Java heap space"
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
5月前
|
监控 Java
【Java】已解决:Java.lang.OutOfMemoryError: GC overhead limit exceeded
【Java】已解决:Java.lang.OutOfMemoryError: GC overhead limit exceeded
477 0
|
7月前
|
Java
什么是Java中的反射(Reflection),如何使用它
什么是Java中的反射(Reflection),如何使用它
|
7月前
|
存储 Java 关系型数据库
8 种 Java- 内存溢出之三 -Permgen space
8 种 Java- 内存溢出之三 -Permgen space
|
7月前
|
缓存 Java
8 种 Java 内存溢出之一:Java Heap Space
8 种 Java 内存溢出之一:Java Heap Space
|
3天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者