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

简介: 《深入浅出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空间则至关重要,以最大程度地减少主要集合的频率。"

相关文章
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
429 27
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
12月前
|
Oracle Java 关系型数据库
JVM深入原理(一+二):JVM概述和JVM功能
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行。
296 0
|
12月前
|
Arthas 存储 Java
JVM深入原理(三+四):JVM组成和JVM字节码文件
目录3. JVM组成3.1. 组成-运行时数据区3.2. 组成-类加载器3.3. 组成-执行引擎3.4. 组成-本地接口4. JVM字节码文件4.1. 字节码文件-组成4.1.1. 组成-基础信息4.1.1.1. 基础信息-魔数4.1.1.2. 基础信息-主副版本号4.1.2. 组成-常量池4.1.3. 组成-方法4.1.3.1. 方法-工作流程4.1.4. 组成-字段4.1.5. 组成-属性4.2. 字节码文件-查看工具4.2.1. javap4.2.2. jclasslib4.2.3. 阿里Arthas
207 0
|
12月前
|
存储 安全 Java
JVM深入原理(五):JVM组成和JVM字节码文件
类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析。
206 0
|
12月前
|
Arthas Java 测试技术
JVM深入原理(六)(一):JVM类加载器
目录6. JVM类加载器6.1. 类加载器-概述6.2. 类加载器-执行流程6.3. 类加载器-分类(JDK8)6.3.1. JVM底层实现的类加载器6.3.1.1. 启动类加载器6.3.2. Java代码实现类的加载器6.3.2.1. 扩展类加载器6.3.2.2. 应用程序类加载器6.4. 类加载器-Arthas查看类加载器
223 0
|
12月前
|
Java 关系型数据库 MySQL
JVM深入原理(六)(二):双亲委派机制
自定义类加载器打破双亲委派机制的方法:复写ClassLoader中的loadClass方法常见问题:要加载的类名如果是以java.开头,则会抛出安全性异常加载自定义的类都会有一个共同的父类Object,需要在代码中交由父类加载器去加载自定义类加载器不手动指定parent会默认指定应用类加载两个自定义类加载器加载同一个类会被认为是两个对象,只有相同的类加载器+想通的类限定名才会被认为是一个对象。
378 0
|
12月前
|
存储 安全 Java
JVM深入原理(七)(一):运行时数据区
栈的介绍:Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存栈的组成:栈:一个线程运行所需要的内存空间,一个栈由多个栈帧组成栈帧:一个方法运行所需要的内存空间活动栈帧:一个线程中只能有一个活动栈帧栈的生命周期:栈随着线程的创建而创建,而回收会在线程销毁时进行栈的执行流程:栈帧压入栈内执行方法执行完毕释放内存若方法间存在调用,那么会压入被调用方法入栈,执行完后释放内存,再执行当前方法,直到执行完毕,释放所有内存。
244 0
|
12月前
|
存储 缓存 安全
JVM深入原理(七)(二):运行时数据区
堆的作用:存放对象的内存空间,它是空间最大的一块内存区域.栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间共享。堆的特点:线程共享:堆中的对象都需要考虑线程安全的问题垃圾回收:堆有垃圾回收机制,不再引用的对象就会被回收方法区的概述:方法区是存放基础信息的位置,线程共享,主要包括:类的元信息:保存了所有类的基本信息运行时常量池:保存了字节码文件中的常量池内容静态常量池:字节码文件通过编号查表的方式找到常量。
179 0
|
12月前
|
缓存 算法 Java
JVM深入原理(八)(一):垃圾回收
弱引用-作用:JVM中使用WeakReference对象来实现软引用,一般在ThreadLocal中,当进行垃圾回收时,被弱引用对象引用的对象就直接被回收.软引用-作用:JVM中使用SoftReference对象来实现软引用,一般在缓存中使用,当程序内存不足时,被引用的对象就会被回收.强引用-作用:可达性算法描述的根对象引用普通对象的引用,指的就是强引用,只要有这层关系存在,被引用的对象就会不被垃圾回收。引用计数法-缺点:如果两个对象循环引用,而又没有其他的对象来引用它们,这样就造成垃圾堆积。
280 0