Unloading class sun.reflect.GeneratedMethodAccessor
问题可能的原因一:由于Xms和Xmx设置大小不当造成的,当程序进行反射操作时没有内存进行此操作。
解决方案:使用-XX:PermSize 与 -XX:MaxPermSize来增加Perm空间大小。因为通过reflect调用方法,实际上,都会生成一个实际的class,并且在perm空间装载。而如果perm空间不够大,同时GC又无法卸载原来装载的类,则会抛出异常。
1.设置MaxPermSize
MaxPermSize 可以设置为最大堆分配 (mx) 的一半。尝试设置 .XX:MaxPermSize=256m,但是,也有人设置到和MX一样的.可以尝试一下.
2.Heap Size
你的ERROR不是OUTOFMEMEROY,所以HEAP的大小应该可用.-Xms512m -Xmx512m 可以试一试.但是最近4月底有人发表意见说设成相同的比太好,会导致GC运行时间过短,导致效率下降.
3.HeapFreeRatio
这项设置对你的问题有没有帮助不太清楚,做一个比较反差的测试,-XX:MinHeapFreeRatio=10,-XX:MaxHeapFreeRatio=20,看看区别,建议最终设置:
-XX:MinHeapFreeRatio=30,-XX:MaxHeapFreeRatio=70
4.NewRatio
有可能是young generation 的大小过大,导致permanent generation大小不够,所以调整NewRatio有可能有用.
-XX:NewRatio=4
结论:尝试将Xms设小了一些,问题仍未解决,只是出现错误的周期变长。 如果初始值(Xms)太大,虽然开始阶段不会有多少GC,但是,由于一开始就在一个很大的空间分配,所以,会出现很多碎片,(这好像叫暗碎片dark heap),就会浪费很多heap,(我好像没有见过SUN的JVM有compaction,即碎片整理)。如果heap的初始值比较小,那么就能减少很多碎片的产生,它能使heap被占满的时间周期变长。
问题可能的原因二:代码中肯定有内存泄露。GC很可能没有及时的回收内存垃圾,所以造成了momery leak。
建议:不能依赖GC回收,真正有效的途径只能是及时释放资源。笨方法之一是不输出 gc 日志,就不会有问题。
与垃圾收集和序列化有关的问题
垃圾收集器与类装入器的交互很密切。在众多的事情当中,收集器检查类装入器的数据结构,来判断哪个类是活动的 —— 也就是说,不应当被当作垃圾收集的。这通常会带来一些意料之外的问题。
场景演示:在这个场景中,序列化以一种意料之外的方式影响了类的垃圾收集(GC):
在这个示例中,SerializationTest 实例化了一个 URLClassLoader,叫做 loader。在装入 SerializationClass 之后,对类装入器的引用被取消。想法是希望这样可以允许类装入器装入的类被垃圾收集掉。这些类的代码如清单 9 和 10 所示:
清单 9. SerializationTest.java
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
publicclassSerializationTest extends ClassLoader {
public static void main(String args[]) {
try {
URLClassLoader loader = new URLClassLoader(new URL[] { new URL(
"file://C:/CL_Article/Serialization/dir1/") });
System.out.println("Loading SerializationClass");
Classc = loader.loadClass("SerializationClass");
System.out.println("Creating an instance of SerializationClass");
c.newInstance();
System.out.println("Dereferencing theclassloader");
c = null;
loader = null;
System.out.println("Running GC...");
System.gc();
System.out.println("Triggering a Javadump");
com.ibm.jvm.Dump.JavaDump();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
清单 10. SerializationClass.java
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
publicclassSerializationClass implements Serializable {
private static final long serialVersionUID = 5024741671582526226L;
public SerializationClass() {
try {
File file = new File("C:/CL_Article/Serialization/test.txt");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(this);
oos.reset();
oos.close();
fos.close();
oos = null;
fos = null;
file = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用 Javadump,可以发现类装入器是否被垃圾收集了。如果在类装入器的列表中出现以下部分,就说明它没有被收集:
------a- Loader java/net/URLClassLoader(0x44DC6DE0), Shadow 0x00ADB6D8,
Parent sun/misc/Launcher$AppClassLoader(0x00ADB7B0)
Number of loaded classes 1
Number of cached classes 11
Allocation used for loaded classes 1
Package owner 0x00ADB6D8
虽然取消对用户定义的类装入器的引用看起来像是一种确保类被垃圾收集的方法,但实际并不是这回事。在前面的示例中,由于 java.io.ObjectOutputStream.writeObject(Object obj) 的使用以及它对 GC 的影响,所以产生了问题。
在调用 writeObject() 时(用来序列化 SerializationClass),对这个类对象的引用就在内部被传递给 ObjectStreamClass 并保存在一个查询表中(也就是内部缓存)。保存这个引用是为了加快日后对同一个类的序列化。
当取消对类装入器的引用时,它装入的类就变成无法进行垃圾收集的了。这是因为在 ObjectStreamClass 查询表中,没有了对 SerializationClass 类的活动引用。ObjectStreamClass 是一个原始类,所以永远不会被垃圾收集。查询表是从 ObjectStreamClass 中的静态字段引用的,而且保存在类本身之中,而不是保存在实例中。所以,对 SerializationClass 的引用存在于 JVM 的生命周期中,所以类就不能被垃圾收集。重要的是,SerializationClass
类有一个到其定义类装入器的引用,所以它也不可能完整地取消引用。
为了避免这个问题,凡是要进行序列化的类,都应当由不需要被垃圾收集的类装入器装入 —— 例如由系统类装入器装入。
分享到:
相关推荐
程序运行要用到的内存大于虚拟机能提供的最大内存就发生内存溢出了, 内存溢出的问题要看业务和系统大小而定,对于某些系统可能内存溢出不常见,但某些系统还是很常见的解决的方法
主要是JVM内存分配及简单的JVM性能调优
(二)MATJVM 内存分析工具.MAT JVM 内存分析工具.MAT JVM 内存分析工具.(二)MATJVM 内存分析工具.MAT JVM 内存分析工具.MAT JVM 内存分析工具.
jvm内存反洗工具:
jvm 内存监控
idea插件JVM内存工具JProfiler11,下载完,即可导入idea,可idea快捷打开使用。
1.jvm内存结构及功能概述 2.Jvm Heap 内存结构 3.Jvm 的内存分配
jvm内存模型,jvm脑图,jvm调优,jvm垃圾回收算法,jvm垃圾回收器,逃逸算法等总结。
JVM 内存管理之道 JVM垃圾回收机制 JVM GC组合 JVM 内存监控工具
java获得jvm内存大小
该文档描述了开发测试环境中Docker及JVM内存限制部署方案
jvm内存结构
MAT JVM 内存分析工具.MAT JVM 内存分析工具.MAT JVM 内存分析工具.
mat用于分析JVM的内存dump信息,是在JVM内存异常时进行内存分析的好工具
JVM内存结构,配置参数,JVM调优监控,待完善
对tomcat jvm内存进行修改,以避免tomcat内存溢出。
jvm内存模型.pdf
JVM内存状况查看方法和分析工具,值得借鉴
JVM 深入学习教程深入分析JVM教程!jvm 内存原型,优化等等
jvm优化;