《深入浅出Java虚拟机 — JVM原理与实战》带你攻克技术盲区,探索各大JVM虚拟机特色 —— JVM故障排除指南(先导篇)

Oracle HotSpot JVM Memory

Java HotSpot VM Heap space

Oracle Java 热点虚拟机中不同 Java 堆内存空间的高级概览。鉴于内存问题的频繁出现,对于任何参与生产支持的人来说,理解这一点非常重要。正确理解 Java VM 堆空间至关重要。您的 Java VM 基本上是 Java 程序的基础,为您提供动态内存管理服务、垃圾收集、线程、I/O 和本机操作等功能。Java 堆空间是运行时 Java 程序的内存"容器",为您的 Java 程序提供所需的适当内存空间(包括 Java 堆和本地堆),并由 JVM 自身管理。

JVM HotSpot虚拟机的内存分为3个内存空间:

  • The Java Heap ------ Java堆
  • The Metaspace 元空间(metaspace) / The PermGen (permanent generation) space ------ PermGen(永久生成空间)
  • The Native Heap (C-Heap) ------ 本地堆(C-Heap)

内存空间分布

内存空间 启动参数 监控策略 描述
Java堆 -Xmx(最大堆空间)-Xms(最小堆尺寸)EX:-Xmx1024m -Xms1024m verbose GC、JMX API、JConsole Java堆正在存储您的主Java程序类实例。
本地堆(C-Heap) 不能直接配置。对于32位虚拟机,CHeap容量=4Gig-Java堆为64位虚拟机,CHeap容量=物理服务器总内存和虚拟内存-Java堆 svmon命令是在AIX操作系统上用于监视内存使用情况的命令。通过svmon命令,可以查看系统中进程的内存使用情况、虚拟内存使用情况、分页空间情况等。 C-Heap正在存储类元数据对象,包括库文件、其他JVM和第三方本机代码对象。
  • verbose GC选项可以在控制台上输出详细的垃圾回收信息,包括垃圾回收的时间、频率以及内存清理情况,有助于开发人员分析程序的内存使用情况以及垃圾回收的效率,从而优化程序的性能。

  • JMX API(Java Management Extensions)是Java平台的一项管理和监控技术,它提供了一套标准的API,用于监控和管理应用程序、设备和服务。通过JMX API,开发人员可以在运行时获取JVM的状态信息,进行性能检测、故障诊断等操作。

  • JConsole是Java自带的一款监控工具,通过JMX技术实现对Java应用程序的监控。开发人员可以使用JConsole来查看应用程序的内存使用情况、线程情况、类加载情况等,还可以通过JConsole执行一些轻量级的分析和管理操作。同时,JConsole也可以通过JMX连接到远程JVM,对远程应用程序进行监控和管理。

注意 C-Heap正在存储类元数据对象,包括库文件、其他JVM和第三方本机代码对象,Oracle也将开始删除热点VM的PermGen空间。

内存分布图

Oracle JRockit JVM Memory

JRockit VM内存被分成两个内存空间:

  • Java堆(YoungGen和OldGen)
  • 本机内存空间(类池、C-Heap、线程)

内存空间分布

内存空间 启动参数 监控策略 描述
Java堆 -Xmx(最大堆空间)-Xms(最小堆尺寸)EX:-Xmx1024m -Xms1024m verbose GC、JMX API、JConsole JRockit Java堆通常被分为年轻Gen(短寿命对象)和OldGen(长寿命对象)。
本机内存空间 不能直接配置。对于32位虚拟机,本地内存空间容量=2-4gig-Java堆进程大小限制为2 GB,3 GB或4 GB,这取决于您的操作系统对于64位虚拟机,本地内存空间容量=物理服务器总内存和虚拟内存-Java堆 总进程大小检查在窗口和Linux,pmap命令在Solaris和Linux - JRockit JRCMD工具 JRockit本机内存空间正在存储Java类元数据、线程和对象,如库文件、其他JVM和第三方本机代码对象。

与IBM VM类似,JRockit VM没有PermGen空间 / metaspace空间。他们仅适用于热点虚拟机。JRockit VM使用本地堆处理类元数据相关数据。

JRockit VM倾向于使用更多的本地内存来换取更好的性能。JRockit没有一个解释模式,只有编译,所以由于它的额外的本机内存需求,进程大小往往使用比同等的Sun JVM大小大几百MB。

这应该不是一个大问题,除非您使用具有大型Java堆要求的32位JRockit;在这种情况下,JRockit虚拟机由于本机堆耗尽导致的内存错误的风险更高(例如对于32位虚拟机,Java堆越大,本机堆剩余的内存更小)。Oracle作为热点spot和JRockit产品线的供应商,其战略是将两个视频管理系统合并到一个JVM项目中,该项目将包含每个项目的最佳特性。这也将简化JVM调优,因为目前不理解这2VM之间的差异可能会导致糟糕的调优建议和性能问题。

关于正确的Java堆大小的提示

由于Java堆容量和调优不足,可能会出现多种性能问题。帮助您确定当前或新的生产环境的最佳Java堆大小,作为起点。其中一些技巧对于预防和解决内存外错误问题也非常有用,包括内存泄漏。

JVM ------ 你总是害怕你不理解的东西

如何期望配置、调整和排除您不了解的问题?您可能永远没有机会编写和改进Java VM规范,但您仍然可以自由地学习它的基础,以提高您的知识和故障排除技能。有些人可能不同意,但从我看来,认为Java程序员不需要知道内部JVM内存管理的想法是一种错觉。

Java VM内存管理比通过-xmx尽可能地设置最大的价值要复杂得多。您必须从各个角度来看,包括您的本地和PermGen空间需求,以及来自物理主机的物理内存可用性(和CPU内核)。

操作系统位数

  • 32位JVM来说,这尤其棘手,因为Java Heap和本机Heap正在竞争中。您的Java堆越大,本地堆就越小。尝试为一个32位虚拟机设置一个大的堆,例如2.5GB+会增加本机内存错误的风险,这取决于您的应用程序占用、线程数量等。

  • 64位JVM解决了这个问题,但您仍然仅限于物理资源的可用性和垃圾收集开销(主要GC收集的成本随着大小的增加而上升)。底线是越大并不总是越好,所以请不要假设您可以在一个16GB 64位JVM 上运行所有的20个Java EE应用程序。

业务流量设置规则:检查动态内存占用需求

您的业务流量通常会决定您的动态内存占用空间。并发用户和请求生成JVM GC"心跳",您可以从各种监视工具中观察到,因为短期和长期寿命对象的创建和垃圾收集非常频繁。

"正如您在上面的JVM图中看到的,Young Generation(年轻代)和Old Generation(老年代)的比例通常为1:3,或者是33%。对于典型的32位JVM,当设置Java Heap大小为2GB时(使用分代和并发收集器),通常会分配500MB给YoungGen空间,而OldGen空间则分配1.5GB。

尽可能减少主要的GC集合频率是实现最佳性能的关键因素,因此理解并估计在峰值负载期间需要多少内存非常重要。同时,您的应用程序和数据类型将决定您需要的内存量。对于需要大量Java堆和大量OldGen空间的应用程序,例如处理大型和非序列化会话数据(long-lived objects)的购物车类型应用程序,通常需要大量内存。而对于无状态和处理大量短命对象的XML应用程序,适当的YoungGen空间则至关重要,以最大程度地减少主要集合的频率。"

相关推荐
V+zmm1013433 分钟前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13141 小时前
常用的缓存技术都有哪些
java
搬码后生仔1 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
凡人的AI工具箱1 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A2 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea
DARLING Zero two♡2 小时前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
Lx3522 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas