JVM 内存分配机制
JVM 内存分配机制
JVM 内存介绍
JVM 是一种用于计算机设备的规范,他是一个虚构出来的计算机,是通过在实际的计算机仿真模拟各种计算机功能来实现的。
Java 语言的一个非常重要的特点就是与平台的无关性,而使用 java 虚拟机是实现这一特点的关键。一般语言要在不通的平台上运行,至少需要编译成不同的目标代码,而引入 java 语言虚拟机后,java 语言在不通平台上运行时不需要重新编译,java 语言使用 java 虚拟机屏蔽了与具体平台相关的信息,使得 java 语言编译程序的时候只需生成在 java 虚拟机上运行的目标代码,就可以在多重平台上不加修改的运行。Java 虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是 Java 能够“一次编译,多出运行”的原因。
JVM 参数配置性能场景
- 寻求当前硬件配置下的最佳参数配置
- 设置线程限制,吞吐量上不去,系统资源使用率不高
- JVM 配置问题,响应时间长,Java 应用 FULLGC 频繁
启动 Java springBoot 应用
java -jar miss-tools.jar --server.port=8081 --server.tomcat.threads.max=10 --server.tomcat.threads.min-spare=50 -Xms512m -Xmx512m -Xmn128m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
JVM 参数
-Xmx3550m
:设置 JVM 最大堆内存为 3550M。-Xms3550m
:设置 JVM 初始堆内存为 3550M。此值可以设置与-Xmx 相同,以避免每次垃圾回收完成后 JVM 重新分配内存Xss128k
:设置每个线程的栈大小-Xmn2g
:设置年轻代大小为 2G,此值关系到 JVM 垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的 3/8-XX:NewSize=1024m
:设置年轻代初始值为 1024M。-XX:MaxNewSize=1024m
:设置年轻代最大值为 1024M。-XX:PermSize=256m
:设置持久代初始值为 256M。-XX:MaxPermSize=256m
:设置持久代最大值为 256M。-XX:NewRatio=4
:设置年轻代与年老代的比值,表示年轻代比年老代为 1:4-XX:SurvivorRatio=4
:设置年轻代中 Eden 区与 Survivor 区的比值。表示 2 个 Survivor 区与 1 个 Eden 区的比值为 2:4-XX:MaxTenuringThreshold=7
:表示一个对象如果在 Survivor 区(救助空间)移动了 7 次还没有被垃圾回收就进入年老代。如果设置为 0 的话,则年轻代对象不经过 Survivor 区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在 Survivor 区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代被垃圾回收的概率,减少 Full GC 的频率,这样做可以在某种程度上提高服务稳定性
GC 回收集器配置
串行收集器器
-XX:+UseSerialGC
:设置串行收集器
并行收集器(吞吐量优先)
-XX:+UseParallelGC
:设置年轻代为并行收集器-XX:ParallelGCThreads=20
:配置并行收集器的线程数,建议配置与 CPU 数目相等-XX:+UseParallelOldGC
:配置年老代垃圾收集方式为并行收集。JDK6.0 开始支持对年老代并行收集-XX:MaxGCPauseMillis=100
:设置每次年轻代垃圾回收的最长时间(单位毫秒)。如果无法满足此时间,JVM 会自动调整年轻代大小,以满足此时间。-XX:+UseAdaptiveSizePolicy
:并行收集器会自动调整年轻代 Eden 区大小和 Survivor 区大小的比例,以满足设定的最长垃圾回收时长。
并发收集器(响应时间优先)
-XX:+UseConcMarkSweepGC
:即 CMS 收集,设置年老代为并发收集。CMS 收集是 JDK1.4 后期版本开始引入的新 GC 算法。它的主要适合场景是对响应时间的重要性需求大于对吞吐量的需求,能够承受垃圾回收线程和应用线程共享 CPU 资源,并且应用中存在比较多的长生命周期对象。CMS 收集的目标是尽量减少应用的暂停时间,减少 Full GC 发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代内存。-XX:+UseParNewGC
:设置年轻代为并发收集。可与 CMS 收集同时使用-XX:CMSFullGCsBeforeCompaction=0
:并发收集器不对内存空间进行压缩和整理,内存使用效率降低。此参数设置运行 0 次 Full GC 后对内存空间进行压缩和整理,即每次 Full GC 后立刻开始压缩和整理内存。-XX:+UseCMSCompactAtFullCollection
:打开内存空间的压缩和整理-XX:CMSInitiatingOccupancyFraction=70
:表示年老代内存空间使用到 70%时就开始执行 CMS 收集,以确保年老代有足够的空间接纳来自年轻代的对象,避免 Full GC 的发生。
java 自带性能分析工具
- jconsloe:
JConsole 是一个基于 JMX(Java Management Extensions)的可视化监控工具,它可以监控 JVM 的各项指标,如内存使用情况、线程数、类加载情况等。通过 JConsole,我们可以实时查看 JVM 的运行状态,对垃圾回收、线程等方面进行优化。 使用方法:在命令行中输入 jconsole 命令启动 JConsole,然后选择需要监控的进程即可。
java -Dcom.sun.management.jmxremote.port=8079 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=${ip} -jar demo.jar
VisualVM
VisualVM 是一个免费的的 Java 代码分析工具,是 Java SE 的一部分,可以帮助我们准确地测量程序的性能指标,如 CPU 和内存使用情况、线程和垃圾回收等。同时,VisualVM 还提供了强大的插件系统,可以扩展其功能,以应对不同的需求。
- 使用方法:在命令行中输入
jvisualvm
命令启动 VisualVM,然后选择需要监控的进程即可。
jps
jstat
jstat 是一个监控 JVM GC 情况的实用工具,可以帮助我们获取 JVM 的各种统计信息,如堆内存使用情况、GC 执行次数和执行时间等。通过对 jstat 输出的数据进行分析,我们可以了解 JVM 的 GC 行为,找出内存泄漏和其他性能问题等。
- 使用方法:在命令行中输入 jstat 命令,然后指定相应的选项即可获取监控数据。
jstat -gc pid 2s 10
jmp
jmap 是一个 Java 堆分析工具,可以用于生成 JVM 堆转储文件以及获取 JVM 的内存映像文件。通过对 jmap 输出的数据进行分析,我们可以诊断程序的内存问题,如内存泄漏、对象创建过多等。
jmap -heap pid
jmap pid
- 使用方法:在命令行中输入 jmap 命令,然后指定相应的选项即可生成相应的文件。
jstack
JPS 和 JSTACK 是 Java 自带的命令行工具,可以用于监控和调试 Java 程序。JPS 可以列出当前所有正在运行的 Java 程序的进程 ID 和类名,而 JSTACK 可以获取指定进程的线程栈信息,帮助我们分析程序的性能问题。
jstack -l pid >1.txt
- 使用方法:在命令行中输入 jps 和 jstack 命令,然后指定相应的选项即可