Java 8 Metaspace:OutOfMemoryError:处理反射通货膨胀

时间:2017-07-05 17:04:04

标签: java spring reflection garbage-collection out-of-memory

网络上有很多links和开放Q&A,但我仍然缺少很多信息。

首先要做的事情

问题:

  

java.lang.OutOfMemoryError:Metaspace

JVM:

java version:  "1.8.0_131"
vm:             Java HotSpot(TM) 64-Bit Server
vm args:       -Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=128m

框架:

  春天,冬眠,检票口,码头

怀疑1:

在使用期间,元空间逐渐增长,并且以下反射类按比例加载到元空间[由jmap -histo cron jobs观察]

sun.reflect.GeneratedConstructorAccessor1299
sun.reflect.GeneratedMethodAccessor6929
sun.reflect.GeneratedSerializationConstructorAccessor4220

可能的解决方案:

一个。由于我们使用的是大量处理反射内容的库,我们认为128m远远不足以在元空间中保存所有generatedXX类。所以我们计划将元空间限制加倍。 -XX:MaxMetaspaceSize =256米

湾我们考虑设置以下

  

-D sun.reflect.noInflation

     

-D sun.reflect.inflationThreshold

怀疑2:

Full GC在达到/占用完整配置的元空间(128m)之前连续运行,并且应用程序变得无响应/慢/有时OOM,因为jvm仅执行FGC。

  

[完整GC(元数据GC阈值)[PSYoungGen:224K-> 0K(698368K)]   [ParOldGen:52910K-> 52933K(1398272K)] 53134K-> 52933K(2096640K),   [Metaspace:92733K-> 92733K(1163264K)],0.1964143 secs] [次:   user = 0.59 sys = 0.00,real = 0.19 secs]

  

Metaspace使用147414K,容量155731K,承诺159616K,   保留1187840K
  班级空间使用17242K,容量19252K,   承诺20352K,保留1048576K

可能的解决方案:

-XX:在vm启动时没有明确提到CompressedClassSpaceSize,这可能会导致过度保留地址空间,从而导致误导的提交sapce,从而导致Full GC。所以明确设置 -XX:CompressedClassSpaceSize = 256m将帮助vm进行正确的内存规划&准备金。

问题:

  1. 怀疑1:有人面临类似问题并得到任何解决方法吗?
  2. 怀疑2:设置-XX:CompressedClassSpaceSize是否真的对元空间规划/保留产生影响并影响GC?有什么指针吗?
  3. 还有其他嫌疑人吗?建议?

1 个答案:

答案 0 :(得分:2)

花了这么多时间后,事实证明没有课堂泄漏,我们是

的受害者

<强> “Reflection Inflation

<?php
class DataBase {

   function opendb() {
       $new_connect = new GConfig();
       $node = mysqli_connect($new_connect->DbServer, $new_connect->DbUser, $new_connect->DbPassword);
       mysqli_select_db($node, $new_connect->DbName);
       mysqli_set_charset($node, "$new_connect->CharSet");
       return $node;
   }

}
?>

我亲自验证过,每次反射生成的第16次使用这种技术来改善响应时间。

最后我们增加了元空间,一切似乎都运行良好。