Java 8 Metaspace: OutOfMemoryError: Dealing with reflection Inflation
Java 8 Metaspace: OutOfMemoryError: Dealing with reflection Inflation
网络上有很多links and open 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
框架:
spring, hibernate, wicket, jetty
嫌疑人 1:
在使用期间,metaspace逐渐增长,随后的反射类按比例加载到metaspace中[通过jmap -histo cron jobs观察]
sun.reflect.GeneratedConstructorAccessor1299
sun.reflect.GeneratedMethodAccessor6929
sun.reflect.GeneratedSerializationConstructorAccessor4220
可能的解决方案:
一个。由于我们正在使用大量处理反射内容的库,因此我们认为 128m 不足以容纳 metaspace 中所有生成的 XX 类。所以我们计划将 metaspace 限制加倍。 -XX:MaxMetaspace大小=256m
b。我们不考虑设置以下
-D sun.reflect.noInflation
-D sun.reflect.inflationThreshold
嫌疑人2:
Full GC 持续 运行 甚至在 reaches/occupies 完整配置的元 space(128m) 之前,应用程序变成 unresponsive/slow/sometime OOM,因为 jvm 只会FGC.
[Full GC (Metadata GC Threshold) [PSYoungGen: 224K->0K(698368K)]
[ParOldGen: 52910K->52933K(1398272K)] 53134K->52933K(2096640K),
[Metaspace: 92733K->92733K(1163264K)], 0.1964143 secs] [Times:
user=0.59 sys=0.00, real=0.19 secs]
.
Metaspace used 147414K, capacity 155731K, committed 159616K,
reserved 1187840K
class space used 17242K, capacity 19252K,
committed 20352K, reserved 1048576K
可能的解决方案:
-XX:CompressedClassSpaceSize 未在 vm 启动时明确提及,这可能会导致过度保留地址 space,从而导致误导性提交空间,从而引发 Full GC。如此明确地设置
-XX:CompressedClassSpaceSize=256m 将帮助 vm 正确规划和保留内存。
问题:
- 怀疑 1:是否有人遇到过类似问题并得到了解决?
- 怀疑2:设置-XX:CompressedClassSpaceSize真的会影响metaspace planning/reserving并影响GC吗?有什么指点吗?
- 还有其他嫌疑人吗?推荐?
花了这么多时间,结果发现没有 class 泄漏,我们是
的受害者
"Reflection Inflation"
package sun.reflect;
/**
The master factory for all reflective objects, both those in
java.lang.reflect (Fields, Methods, Constructors) as well as their
delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
**/
public class ReflectionFactory {
// "Inflation" mechanism. Loading bytecodes to implement Method.invoke() and Constructor.newInstance() currently costs
// 3-4x more than an invocation via native code for the first invocation (though subsequent invocations have been benchmarked
// to be over 20x faster). Unfortunately this cost increases startup time for certain applications that use reflection
// intensively (but only once per class) to bootstrap themselves. To avoid this penalty we reuse the existing JVM entry points
// for the first few invocations of Methods and Constructors and then switch to the bytecode-based implementations.
我亲身验证过,在每16次反射生成时使用这个技术来提高响应时间。
最后我们增加了元空间,一切似乎都正常。
网络上有很多links and open 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
框架:
spring, hibernate, wicket, jetty
嫌疑人 1:
在使用期间,metaspace逐渐增长,随后的反射类按比例加载到metaspace中[通过jmap -histo cron jobs观察]
sun.reflect.GeneratedConstructorAccessor1299
sun.reflect.GeneratedMethodAccessor6929
sun.reflect.GeneratedSerializationConstructorAccessor4220
可能的解决方案:
一个。由于我们正在使用大量处理反射内容的库,因此我们认为 128m 不足以容纳 metaspace 中所有生成的 XX 类。所以我们计划将 metaspace 限制加倍。 -XX:MaxMetaspace大小=256m
b。我们不考虑设置以下
-D sun.reflect.noInflation
-D sun.reflect.inflationThreshold
嫌疑人2:
Full GC 持续 运行 甚至在 reaches/occupies 完整配置的元 space(128m) 之前,应用程序变成 unresponsive/slow/sometime OOM,因为 jvm 只会FGC.
[Full GC (Metadata GC Threshold) [PSYoungGen: 224K->0K(698368K)] [ParOldGen: 52910K->52933K(1398272K)] 53134K->52933K(2096640K), [Metaspace: 92733K->92733K(1163264K)], 0.1964143 secs] [Times: user=0.59 sys=0.00, real=0.19 secs]
.
Metaspace used 147414K, capacity 155731K, committed 159616K, reserved 1187840K
class space used 17242K, capacity 19252K, committed 20352K, reserved 1048576K
可能的解决方案:
-XX:CompressedClassSpaceSize 未在 vm 启动时明确提及,这可能会导致过度保留地址 space,从而导致误导性提交空间,从而引发 Full GC。如此明确地设置 -XX:CompressedClassSpaceSize=256m 将帮助 vm 正确规划和保留内存。
问题:
- 怀疑 1:是否有人遇到过类似问题并得到了解决?
- 怀疑2:设置-XX:CompressedClassSpaceSize真的会影响metaspace planning/reserving并影响GC吗?有什么指点吗?
- 还有其他嫌疑人吗?推荐?
花了这么多时间,结果发现没有 class 泄漏,我们是
的受害者"Reflection Inflation"
package sun.reflect;
/**
The master factory for all reflective objects, both those in
java.lang.reflect (Fields, Methods, Constructors) as well as their
delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
**/
public class ReflectionFactory {
// "Inflation" mechanism. Loading bytecodes to implement Method.invoke() and Constructor.newInstance() currently costs
// 3-4x more than an invocation via native code for the first invocation (though subsequent invocations have been benchmarked
// to be over 20x faster). Unfortunately this cost increases startup time for certain applications that use reflection
// intensively (but only once per class) to bootstrap themselves. To avoid this penalty we reuse the existing JVM entry points
// for the first few invocations of Methods and Constructors and then switch to the bytecode-based implementations.
我亲身验证过,在每16次反射生成时使用这个技术来提高响应时间。
最后我们增加了元空间,一切似乎都正常。