JVM虚拟机讲解,底层原理与性能优化关键点是什么?

JVM的底层本质是一台运行在操作系统之上的抽象计算机,它负责把字节码翻译成机器指令并管理内存;性能优化的关键,不是堆内存越大越好,而是让垃圾回收节奏与业务特征匹配。

JVM 像一位带着行李自己旅行的大管家,Java 代码经过编译变成 .class 字节码,自身无法被操作系统直接执行,JVM 就把字节码逐条解释、编译成当前系统的机器码,同时负责分配内存、回收垃圾、协调线程,理解了它在干什么,你就理解了 JVM 调优为什么那么多人头疼,因为它实际上是在管理两个东西:内存和线程

黑马程序员JVM完整教程,Java虚拟机快速入门,全程干货不拖沓
加载中
黑马程序员JVM完整教程,Java虚拟机快速入门,全程干货不拖沓
146.3万1.6万3.7万
原视频地址

JVM内存模型详解与运行时数据区是怎么分工的

JVM 运行时把内存划分成几个区域,各管各的活,这套划分规则在 Oracle 官方文档里有明确定义,业内统称为“内存模型”,面试和工作中聊的“JVM内存模型详解”,99% 是在讲下面这些区域的分工。

堆区:对象的大本营

堆区是所有对象实例和数组的居住地,这块内存是所有线程共享的,也是垃圾回收的主战场,堆内部会进一步划分为年轻代和老年代,年轻代又分为 Eden 区和两块幸存者区。

绝大多数新建对象先进入 Eden 区,经过一轮垃圾回收后仍然存活的对象,会被移动到幸存者区,幸存者区的对象经过多次回收仍然存活,最后晋升到老年代。这个晋升过程依赖年龄计数器,每熬过一次回收年龄加一,超过阈值就能晋级。

关于堆的默认大小,行业共识是逻辑内存的四分之一作为上限,但这个数值并不适合所有业务,后面性能优化部分我会重点展开。

栈区:方法执行的临时舞台

栈区是线程私有的,每个线程启动时,JVM 都会为他分配一块栈空间,每当执行一个方法,JVM 就压入一个栈帧,栈帧里存放局部变量、操作数栈、动态链接和方法出口。

栈的生命周期跟方法绑定,方法执行完毕,栈帧自动弹出,无需垃圾回收器介入,所以局部变量用完就销毁,效率比堆高得多,不过如果方法递归调用深度过大,就会出现 StackOverflowError,这是栈空间耗尽的信号。

元空间与直接内存

JDK 8 以前,类元数据存储在永久代;JDK 8 之后,永久代被元空间取代,元空间不在 JVM 堆内,而是使用了操作系统直接内存,类信息、常量池、方法描述符都放在这里。

直接内存也叫堆外内存,NIO 类库可以通过 DirectByteBuffer 直接使用它,Java 的 netty、kafka 客户端大多采用堆外内存做数据缓冲,减少一次拷贝,这个区域如果使用不当也会撑爆,排查的时候别只盯着堆。

JVM虚拟机讲解,底层原理与性能优化关键点是什么?

JVM垃圾回收器怎么选:从 Serial 到 ZGC 的对比

JDK 究竟自带多少种垃圾回收器?答案是一套演进谱系,垃圾回收器选择,在相当大程度上决定了你的停顿时间。

分代回收器的阵营

JVM 早期使用分代收集器,包括 Serial 单线程回收器、Parallel 并行回收器和 CMS 并发标记清除回收器。

  • Serial:单线程回收,适合单核环境或小应用。
  • Parallel:多线程并行回收,吞吐量优先,适合批量计算和后台任务。
  • CMS:以最短停顿为目标,但会产生碎片,JDK 14 已被官方移除。

JDK 9 之后,G1 成为默认回收器,G1 把堆划分成多个相等区域,每次回收一部分区域的垃圾,而不是全堆扫描,它设计目标是在停顿可控的同时兼顾吞吐量,多数 Java 服务跑在 G1 上。

JDK 15 之后,ZGC 正式转正,ZGC 支持 TB 级堆,停顿时间几乎不随堆变大而增加,但代价是更耗 CPU。

不同回收器使用场景对比

回收器 核心思想 适合业务 代价
Serial 单线程串行 桌面端、极小堆 停顿较长
Parallel 多线程并行 离线计算、日志分析 停顿较长
CMS 并发标记清除 旧系统兼容遗留场景 碎片化,已移除
G1 区域化分代 大多数线上 Java 服务 大堆下停顿随堆增长
ZGC 并发引用染色 大堆、超低延迟场景 CPU 开销较高

选型建议

行业共识是:默认 G1 是一般服务的最优解,别急着换,如果业务要求极端低延迟且堆内存较大,再考虑 ZGC,小内存应用用 Serial 反而更省资源。

JVM性能优化关键点:从参数到大盘观测

性能优化不是调一个参数就完事,而是先观测,再定位,最后才调整参数,下面这套流程覆盖 Java 线上 JVM 优化的高频操作路径。

调整堆大小:先看实际占用

很多人喜欢把堆直接设置成很大的数值,效果往往适得其反,堆太大,垃圾回收单次时间长;堆太小,频繁触发 Full GC,CPU 白忙活。

合理做法是先在负载测试环境开启 GC 日志:

java -Xlog:gc:gc.log

JVM虚拟机讲解,底层原理与性能优化关键点是什么?

跑几天业务后,观察 GC 日志里堆实际使用峰值,然后设置:

-Xms4g -Xmx4g

将初始堆和最大堆设为一致,避免运行期动态扩容带来的性能抖动。这个是 JVM 调优最佳实践里最基础的一步

Java线上OOM怎么排查:三步定位法

线上发生 OutOfMemoryError,很多团队第一反应是重启大法,但重启之后还会复现,不如按这套流程走:

  1. 启动时加上堆转储参数,让 JVM 在 OOM 时自动保存现场:
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/dump
  2. 使用 jmap 手动导出现存堆快照:
    jmap -dump:format=b,file=heap.hprof <pid>
  3. 用 MAT 或 VisualVM 分析直方图,查看哪个对象实例数量最多、哪个类占用的 Retained Heap 最大。

定位到对象后,多数情况是因为集合类缓存无限增长,或 SQL 取数没有分页,修复代码,比调大堆更有效。

CPU 飙高的排查命令

CPU 使用率居高不下,常见原因有两个:频繁 Full GC 和业务线程死循环。

  • 先用 top -Hp <pid> 找出CPU最高的线程 ID。
  • 将线程 ID 转成十六进制:printf '%xn' <tid>
  • 执行 jstack <pid> > thread.log,在线程快照里搜索十六进制数字对应的线程栈。

这个时候你能看到它到底卡在哪段代码里,如果是 GC 线程占据大量 CPU,那要回去看 GC 日志;如果落在业务方法上,那就是代码逻辑问题。

参数优化四板斧

JVM 参数成百上千,但调优只围绕几个核心点:

  • 堆大小-Xms-Xmx 保持一致。
  • 元空间上限:设置 -XX:MaxMetaspaceSize,防止类加载器泄漏导致换机。
  • GC 日志开关-Xlog:gc 记录详情。
  • OOM 自动转储-XX:+HeapDumpOnOutOfMemoryError

对于 G1 回收器,还可以设置 -XX:MaxGCPauseMillis 给出停顿目标,但别设置过小,否则 G1 会为了迎合目标而频繁回收,反而拉低吞吐量。

三个容易踩的坑

  • 盲目复制网上“无敌参数模板”,不经过压测直接上生产,容易出大事。
  • 频繁调优堆大小而不是修复代码问题,堆只是容器,代码里的对象持有才是根因。
  • 忽略堆外内存,DirectByteBuffer 使用过多会直接抛 OOM,但堆转储文件里却看不到多少对象。
  • JVM虚拟机讲解,底层原理与性能优化关键点是什么?

JVM性能优化常见参数有哪些:一句话讲清关键参数

JVM 面试里,JVM性能优化常见参数有哪些”这个问题其实问的是基本功,把下面这张参数表记牢,基本就能应付绝大多数场景:

  • -Xms:初始堆大小。
  • -Xmx:最大堆大小。
  • -Xmn:年轻代大小,过大则老年代变小。
  • -XX:MaxMetaspaceSize:类元数据上限。
  • -XX:+UseG1GC:显式启用 G1。
  • -XX:MaxGCPauseMillis:最大 GC 停顿目标。
  • -XX:ParallelGCThreads:并行 GC 线程数。
  • -XX:ConcGCThreads:并发标记线程数。

设置参数时,务必跟踪到底层原理。-Xmn 设置过大,年轻代对象晋升到老年代的机会变少,短期内频繁 Young GC 反而降低整体性能,任何参数调整后都要用 jstat 观察:

jstat -gcutil <pid> 1000 10

这个命令每秒输出一次各代内存使用率和 GC 耗时,连续输出 10 次,基本能判断出参数调整是否起了效果。

关于JVM知识的高频疑问解答

从堆内存角度,JVM内存模型和Java内存模型有区别吗?

有本质区别,JVM内存模型描述的是运行时数据区的划分,也就是前面提到的堆、栈、方法区等具体内存区域,而 Java 内存模型是围绕着多线程并发场景定义的一套抽象规则,解决的是可见性、有序性和原子性问题,对应 synchronizedvolatile 这些关键字背后的语义,前者讲数据放哪里,后者讲多线程读写数据时怎么保证正确性。

线上 JVM 堆内存一直偏高但没到最大值,需要人为干预吗?

多数情况下不需要立即干预,先执行 jstat -gcutil <pid> 观察老年代使用率和 Full GC 频率,如果老年代占比持续上升且一直没有回落到安全水位,说明存在对象长期无法回收的可能,这时候再配合 jmap -dump 检查是否有对象意外持有大集合,优先处理代码层面的持有关系,而不是增加堆大小。

JDK 21 里 G1 和 ZGC 怎么选?

JDK 21 中 G1 仍是默认垃圾回收器,ZGC 从实验状态转正之后已经经过多个版本迭代,在低延迟方向上表现稳定,如果你的服务堆内存较小且追求最大吞吐量,继续用 G1;如果堆内存超过几十 GB,并且业务要求极端响应速度,ZGC 带来的停顿优势优于吞吐量的轻微下降,选择核心在于衡量你的业务到底缺停顿时间,还是缺 CPU 余量。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://idctop.com/article/615173.html

(0)
备用DNS服务器地址在哪设置?详细步骤是怎样的?
上一篇 2026年9月1日 17:11
域名中子域名为什么用点号来分隔?子域名怎么设置有何作用?
下一篇 2026年9月1日 17:11

相关推荐

  • 广告网站建设公司哪家好?专业建站公司怎么选

    选择专业的广告网站建设公司进行合作,是企业实现数字化转型的核心策略,直接决定了品牌在线上的获客效率与投资回报率,一个优质的广告网站不仅仅是企业的电子名片,更是24小时不间断工作的超级销售员,在当前竞争激烈的互联网环境中,网站建设必须摒弃传统的模板化思维,转向以数据驱动、用户体验为核心的品牌营销型建设模式, 为什……

    2026年4月3日
    8500
  • 多域名通配符证书能保护多少个二级域名?通配符证书支持几个子域名

    多域名通配符证书(Wildcard SSL)能保护的主域名及其所有直接二级域名,具体数量取决于证书购买时的“子域层级”设置,通常默认为保护主域名下的第一层二级域名(如 *.example.com),若需保护多级嵌套域名(如 a.b.example.com),则需购买支持多级通配符的特定版本或扩展证书,在网络安全……

    2026年6月20日
    2100
  • hp服务器租用哪家靠谱?2026年最新价格及配置清单

    选择HP服务器租用时,核心结论是:对于追求极致稳定性与售后响应速度的企业,HP ProLiant系列依然是首选,但需重点关注2026年后的维保政策与云端混合部署的兼容性,以平衡成本与性能,在数据中心建设与企业IT架构升级的当下,服务器选型不再仅仅是硬件参数的比拼,而是对业务连续性、运维效率及长期持有成本的综合考……

    服务器宽带 2026年6月9日
    3200
  • 广州bgp高防ip怎么做?广州BGP高防IP配置方法详解

    广州BGP高防IP的配置核心在于精准的流量调度与智能清洗策略的部署,通过将高防IP作为业务流量的“盾牌”,隐藏真实服务器地址,利用BGP协议的多线互联特性,实现防御与加速的双重目标,企业无需更换原有服务器架构,只需通过DNS解析变更与路由指向,即可构建起应对大流量DDoS攻击的坚固防线,这一方案目前是华南地区企……

    2026年3月31日
    7100
  • 服务器带宽配置选错了?服务器带宽多少才合适

    服务器卡顿、加载缓慢,核心症结往往不在于服务器本身的硬件配置不足,而在于带宽配置与实际业务流量模型的不匹配,带宽作为数据传输的“高速公路”,其宽度直接决定了用户请求响应的速度与稳定性,一旦带宽配置选错,服务器CPU性能再强也只能处于“空转”等待状态,用户体验将直线下降,解决卡顿问题的首要任务,是精准诊断带宽瓶颈……

    2026年3月6日
    13000
  • HP云服务器在哪?惠普云服务器官网入口

    HP云服务器主要依托于HPE GreenLake云平台及全球数据中心部署,国内用户通常通过阿里云、腾讯云等主流云服务商的HPE硬件实例或HPE官方合作伙伴进行访问与购买,具体物理节点分布取决于所选区域和服务类型,HP云服务器的全球部署与国内访问路径提到HP云服务器,很多人第一反应是惠普这个老牌硬件巨头,但需要厘……

    2026年6月10日
    3710
  • pro域名是什么意思?pro域名注册有什么要求

    Pro域名是“专业”的英文缩写,主要面向专业人士、企业及技术专家,象征着权威、信任与行业深度,是构建高端品牌形象的首选顶级域名,在域名选择的迷宫中,许多人容易混淆.com、.net与.pro的区别,.com追求的是通用与普及,.net侧重网络基础设施,而.pro则是一门心思要打造“专家人设”,如果你正在为个人品……

    2026年6月21日
    2100
  • HTML设置字体如何移动?css文字滚动特效代码

    在HTML中实现字体移动,核心方案是利用CSS3的@keyframes动画配合transform属性,或者通过JavaScript动态修改元素的left或margin-left值,其中CSS动画方案性能更优且代码更简洁,很多开发者在初次接触前端动效时,往往容易混淆“字体移动”与“文字滚动”的概念,字体移动通常指……

    2026年6月3日
    5500
  • html输出js信息怎么做?js动态生成html内容

    在HTML中输出JS信息,核心在于利用DOM操作动态更新页面内容,推荐通过document.getElementById获取元素后使用textContent或innerHTML赋值,这是最标准且高效的实现方式,前端开发中,将JavaScript计算出的数据实时展示在网页上,是构建动态交互应用的基础技能,很多初学……

    2026年6月4日
    3800
  • biz域名注册费用高吗,. biz域名一年多少钱

    .biz域名首年注册价格通常在20元至50元人民币之间,续费价格则在40元至80元人民币左右,具体费用取决于注册商促销力度及是否包含隐私保护服务,在2026年的互联网生态中,域名早已超越了单纯的网址标识功能,成为企业品牌资产的核心组成部分,.biz作为通用顶级域名(gTLD)的一员,凭借其商业属性鲜明的后缀,依……

    2026年6月23日
    3300

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注