知识卡片
JVM 32G现象:多个小heap实例优于单个巨大heap
内容
面对一台拥有128G内存的物理机,一个自然的想法是配置一个JVM实例、给它分配尽可能大的heap(比如64G),这样似乎能让Java程序用满整台机器的内存。但实践和官方文档(”Don’t Cross 32 GB!“)都指向相反的结论:应该配置多个较小heap的JVM实例(比如每个32G左右),而不是一个巨大heap的单实例——这背后是JVM在heap大小超过32G这个临界点时会失去一项重要的内存优化(压缩对象指针,Compressed OOPs),导致即使多给了内存(比如从32G提高到40G),实际有效性能反而不如刚好卡在31G以下的配置,这个反直觉的现象被称为”JVM 32G现象”。这个案例提示了一条在容量规划中容易被忽视的原则:某些底层运行时(不只是JVM)的资源利用效率并不是随着分配资源的增加而线性提升的,可能存在特定的技术临界点,一旦跨过这个临界点,某些内部优化机制会失效,导致资源利用率不升反降;在做”给单个实例分配多少资源”这类决策之前,有必要去确认所使用的运行时环境是否存在这类已知的非线性拐点,而不能想当然地认为”资源分配得越多、性能就一定越好”。这也是为什么很多高内存机器上部署Elasticsearch/JVM类服务时,更倾向于用多个受限heap的实例去瓜分整机内存,而不是让单个实例吃满所有可用内存。
参考来源
- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.8 亿级规模的Elasticsearch优化实战"节,"2.8.3 其他"(源文件:_epub-src/OEBPS/Text/Chapter2_8_4.xhtml)
- 结论依据:原文说明"对拥有128G内存的机器来说,是选择配置一个JVM,然后是巨大的heapsize(如64G)?还是选择配置配多个JVM instance搭配较小的heapsize(如32G)?我的建议是后者……当heap sizing超过32G时,哪怕使用更多的内存(比如40G),效果反而不如31G!这就是JVM 32G现象",直接支撑本卡片结论。
- 原始内容:对拥有128G内存的机器来说,是选择配置一个JVM,然后是巨大的heapsize(如64G)?还是选择配置配多个JVM instance搭配较小的heapsize(如32G)?我的建议是后者……当heap sizing超过32G时,哪怕使用更多的内存(比如40G),效果反而不如31G!这就是JVM 32G现象。