java.lang.OutOfMemoryError: Compressed class space

我们在java-8-oracle上运行。

六个月前,我们迁移到了 java8。

在过去的几天里,我们不时收到OOME,但我们无法识别或重现问题。

当我们执行对服务器(tomcat)的调用时,我们在堆栈跟踪上收到此错误:

java.lang.OutOfMemoryError: Compressed class space

重新启动服务器可以解决问题。对其他服务器的相同调用有效,对同一服务器的另一种类型的另一种调用也是如此。

在查看 gc 时.log我们会看到:

2015-05-27T16:05:42.991+0000: 98774.440: [Full GC (Last ditch collection) 98774.440: [CMS: 575745K->575330K(3495936K), 0.8687777 secs] 575745K->575330K(4107008K), [Metaspace: 97940K->97940K(1396736K)], 0.8696093 secs] [Times: user=0.95 sys=0.00, real=0.88 secs]
2015-05-27T16:05:55.486+0000: 98786.935: [Full GC (Metadata GC Threshold) 98786.935: [CMS: 573414K->578735K(3495936K), 0.9372859 secs] 925046K->578735K(4107008K), [Metaspace: 99428K->99428K(1396736K)], 0.9386626 secs] [Times: user=1.01 sys=0.00, real=0.94 secs]

jstat -gc返回:

 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
87296.0 87296.0  0.0   3151.4 523776.0 148284.4 3495936.0   574868.5  1395640.0 98066.3 1048576.0 11339.1  12165  636.851  223   116.957  

753.808

我在jstat日志或gc日志中都没有看到任何内存问题。

尝试运行挂起:jmap -clstats

Attaching to process ID 5110, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.25-b02
finding class loader instances ..

答案 1

我们遇到了类似的问题。不幸的是,堆转储不会帮助你,因为这些类不在堆中,而是在本机内存中。在 JVM 设置中启用这些功能,以便对装入的类进行故障诊断:

-XX:+PrintGCDetails -XX:+TraceClassUnloading -XX:+TraceClassLoading

在我们的例子中,问题是JAXBContext.newInstance不是单例。

祝你好运,阿尔伯特


答案 2

对于压缩的 oops 和压缩的类指针,由于必要的指针重整,类的可用空间受到限制。1GB在你的情况下。

这是很多类,所以这可能表明应用程序中的某些内容正在创建很多类并且从未释放它们。应用程序重新加载可能?

如果您确定您的应用程序只需要那么多的内存用于类,则可以尝试通过 来提高限制或通过 禁用压缩类指针。-XX:CompressedClassSpaceSize=...-XX:-UseCompressedClassPointers

请注意,默认情况下,压缩类空间 + 压缩堆(+ 一些开销)不能超过 32GB。虽然,AIUI,改变对象对齐方式可以进一步提高这个限制。

否则,您应该进行堆转储并分析加载的类的保留因素。


推荐