
尚硅谷教育
《剑指JVM:虚拟机实践与性能调优》共分5篇:引言篇讲述了Java与Java虚拟机的关系,以及Java虚拟机的相关知识;第1篇讲述了运行时数据区,涉及Java内存区域的各个核心结构,以及对象创建的各种细节;第2篇讲述了垃圾收集,涉及各种收集算法、垃圾收集器;第3篇讲述了字节码与类的加载;第4篇讲述了性能监控与调优,带领读者学习Java虚拟机常用的监控与调优工具,并附有企业级的性能调优案例。本书配套视频,可以关注尚硅谷教育公众号获取。
我觉得是非常好,非常实用的一本书。有大量贴合简化但又贴合实际的代码案例和过程插图,有很强烈的实用主义风格,并且实际上是钻的很深的。我认为很适合工作1-3年的java工程师阅读。 其实我觉得JVM调优并没有看起来那么高大上,尤其在中国互联网环境下,很多初级工程师(工作3,5年内)就需要一个人负责一大摊子业务,就很可能接触到性能瓶颈,调优的问题。 而调优并不像我们想象的深钻20年,然后把95分调到98分。更多是知识点扫盲,从60分调到80分。所以即使是初级工程师,也是有必要了解的。 至于本书的内容,我觉得可以分两部分看待: 一部分讲述结构,原理,比如JVM里的堆,栈,方法区,垃圾回收机制及各种垃圾收集器等等这些部分可以仔细阅读,即使自己工作中不涉及jvm调优。去了解这一部分是有助于在头脑中建立概念,对写代码,思考排查线上问题大有裨益的。 另一部分像书里会很深入地介绍字节码的编译,甚至字节码指令的含义,以及一些垃圾处理的细节等这样的内容。我认为实际上没必要细读,如果真的用到了,可以再回来当工具书翻阅即可。
花了很长时间把这本大部头的书读完了,总体还是很不错的,对底层原理讲解很详细,不过可能是时间问题,书中还是有不少错字和漏字的情况,这本书虽然比起周志明的书逊色一些,但是总体也不差,读起来还是有很多收获的!
- 剑指JVM.虚拟机实践与性能调优 2023.5; Java与JVM关系/JVM相关知识 运行时数据区.Java内存区域的各个核心结构/对象创建的各种细节 GC.算法/垃圾收集器 字节码与类的加载 性能监控与调优.企业级的性能调优案例
最初读了《深入理解java虚拟机》,因为版本太老,信息旧了,搜到这本书。相比来说,本书更值得推荐,更详细、实操性更强,把复杂的内容讲得很清晰通透,属于少有的优秀教材,颠覆了对培训机构出版教材的认知。
讲理论的同时,还会伴随着字节码调用分析,对于理解jvm的各概念或工作机理都很有帮助。后面的工具介绍、调优案例对实践中分析程序性能也很有帮助,虽然介绍的不是太详细。总体来说,这本书值得阅读。
JVM 虚拟机实践与性能调优核心公式 1. 内存相关核心公式 1. JVM 堆内存可用空间公式 可用堆空间 = 最大堆内存(-Xmx) - 最小堆内存(-Xms) + 剩余堆内存 2. 堆内存使用率公式 堆内存使用率 = (已使用堆内存 / 当前堆内存大小) × 100% 3. 新生代对象晋升老年代触发条件 晋升阈值 = 新生代年龄计数器最大值(-XX:MaxTenuringThreshold) 当对象年龄 ≥ 晋升阈值 时,对象进入老年代 4. Minor GC 触发条件 Eden区使用率 = (Eden区已用空间 / Eden区总空间) × 100% 当 Eden区使用率达到阈值时,触发 Minor GC 2. GC 性能核心公式 1. GC 吞吐量公式 吞吐量 = (应用程序运行时间 / (应用程序运行时间 + GC 总耗时)) × 100% 2. GC 停顿时间公式 单次 GC 停顿时间 = GC 结束时间 - GC 开始时间 平均 GC 停顿时间 = 总 GC 停顿时间 / GC 次数 3. Full GC 触发频率公式 Full GC 频率 = Full GC 次数 / 运行时长(单位:次/小时) 3. 线程与CPU相关公式 1. 线程 CPU 使用率公式 线程 CPU 使用率 = (线程占用 CPU 时间 / 总 CPU 时间) × 100% 2. JVM 进程 CPU 使用率公式 JVM CPU 使用率 = (JVM 进程占用 CPU 时间 / 系统总 CPU 时间) × 100% 4. 类加载与内存泄漏相关公式 1. 类加载率公式 类加载率 = 已加载类数量 / 总可加载类数量 × 100% 2. 内存泄漏判定公式 内存泄漏趋势 = 多次 GC 后老年代内存占用差值 / 时间间隔 若差值持续为正且无下降,大概率存在内存泄漏 5. 调优目标量化公式 1. 响应时间优化目标 目标响应时间 = 原响应时间 - (原响应时间 × 调优目标百分比) 2. 内存占用优化目标 目标内存占用 = 原内存占用 × (1 - 调优目标百分比)
这本书对于理解和应用虚拟机技术以及优化性能方面提供了非常宝贵的指导和深入见解。 首先,书中系统地介绍了虚拟机的基础概念、原理、工作原理和常见问题。深入浅出地讲解风格使得复杂的概念易于理解,并通过丰富的实例帮助读者将知识应用于实践中。 其次,该书不仅提供了理论知识,还详细介绍了虚拟机的常见问题和调优技巧。并提供了一些建议和实践案例来解决这些问题。这些实用的技巧对于从事虚拟化平台管理和优化工作的专业人士来说至关重要。 总之,这是一本深入、全面、实用且易读的书籍。它是一本对于想要在虚拟化领域深入学习和应用的读者来说不可或缺的参考资料!
Compile Once, Run Anywhere. JVM 的职责:解释执行字节码,能够运行任何编译成字节码的计算机语言。 跨平台性:Java 解决了跨平台的问题,并且 JVM 也支持其他语言的跨平台。 虚拟机的强大:尽管 Java 语言本身并非最强大,但 JVM 被公认为最强大的虚拟机。 虚拟机概述 定义:虚拟机是一种软件,用于执行虚拟计算机指令。可以分为系统虚拟机和程序虚拟机。 三层架构:类装载器子系统:通过类装载器机制将编译好的字节码存放在 JVM 内存区域。 运行时数据区:存储运行时数据的区域,包括方法区、堆、Java 栈、程序计数器和本地方法栈。 执行引擎层:包含解释器、JIT 编译器和垃圾回收器(GC)。 编译与解释 半编译半解释型语言:Java 采用 JIT 即时编译技术,将常用方法或代码块编译成本地机器码。 指令集架构:基于栈的指令集架构,另一种是基于寄存器的指令集架构。 基于栈式架构的特点 设计和实现简单:适用于资源受限的系统。 避开寄存器分配问题:使用零地址指令方式操作。 指令集小:编译器实现更容易。 不需要硬件支持:跨平台性更好。 基于寄存器架构的特点 典型应用:如 x86 指令集和 Android 的 Dalvik 虚拟机。 依赖硬件:可移植性差,但性能优越。 指令直接由 CPU 执行:执行效率更高。 少量指令完成操作。 指令类型:通常为一地址指令、二地址指令和三地址指令,而基于栈式架构的是零地址指令。 设计总结 Java 指令基于栈设计:为了实现跨平台性,不同平台的 CPU 架构不同,无法设计为基于寄存器。 优点:跨平台、指令集小、编译器易于实现。 缺点:性能较差,实现同样功能需要更多指令。 JVM 的生命周期 三个状态:启动、执行和退出。 历史背景:早期 Sun Classic/C++ 程序的 VM 无法高效协同解释器和编译器,导致 “Java 语言很慢” 的印象。 GCIH 技术 GC Invisible Heap:将生命周期较长的 Java 对象移到 heap 之外,GC 无法管理 GCIH 内部的 Java 对象,降低 GC 回收频率并提升效率。GCIH 对象还可在多个 JVM 进程中共享。 数据区域类型 线程共享数据区:在 JVM 启动时创建,退出时销毁。 线程私有数据区:在创建线程时创建,线程退出时销毁。 HotSpot 虚拟机 线程与本地线程直接映射。 未捕获异常:可能导致 Java 线程终止,进而决定 JVM 是否终止。 守护线程:在后台完成系统服务,仅当只有守护线程时,JVM 自动退出。 程序计数器 抽象模拟物理寄存器。 字节码解释器:通过改变计数器值选取下一条字节码指令,指示程序控制流。 线程私有:每个线程都有自己的计数器,生命周期与线程一致。 用途:存储字节码指令地址,支持线程切换后续执行。 虚拟机栈 栈帧组成:包括局部变量表、操作数栈、动态链接、方法返回地址和附加信息。 线程私有:虚拟机栈的生命周期与线程一致。 栈的特点:快速有效的分配存储方式,访问速度快,存在内存溢出但无垃圾回收问题。 栈帧内容 局部变量表:存储方法参数和局部变量。 操作数栈:用于表达式计算。 动态链接:指向运行时常量池的方法引用。 方法返回地址:存储方法正常退出或异常退出的信息。 栈顶缓存技术 原理:将频繁访问的栈顶元素缓存到物理 CPU 的寄存器中,减少内存读写次数,提高执行效率。 本地方法接口JNI:Java 调用非 Java 代码的接口。 本地方法栈传统栈支持:用于本地方法执行。 堆堆与栈:堆是存储单元,栈是运行单元。栈中处理的数据主要来源于堆。 线程共享:堆是所有线程共享的运行时内存区域。 唯一性:每个 JVM 实例对应一个堆空间。 逻辑连续:尽管物理上不连续,但逻辑上视为连续。 分代收集理论:堆内存分为新生代和老年代。 垃圾回收:新生代 GC(Minor GC)频繁,老年代 GC(Major GC)较少。 新生代 GC 触发机制:新生代空间不足时触发。 频率:较高,但速度快。 STW:Minor GC 会暂停其他用户线程,待回收结束后恢复。 老年代 GC 触发机制:老年代空间不足或对象从老年代消失时触发。 速度:较 Minor GC 慢,STW 时间长。 Full GC:触发机制包括调用 System.gc()、老年代或方法区空间不足等。 TLAB 私有缓存区域:每个线程分配在 Eden 区内。 默认大小:占 Eden 区的 1%,可通过参数调整。 内存分配失败:会尝试使用加锁机制在 Eden 区分配内存。 堆外存储 逃逸分析:用于优化对象分配,减少堆内存占用,提高性能。 标量替换:减少堆内存占用的技术。 逃逸分析优化 栈上分配:将堆分配转化为栈分配。 同步省略:对于仅被一个线程访问的对象,可以不考虑同步。 分离对象或标量替换:不需要作为连续内存结构存在的对象可以存储在栈中。 JDK 8 变化 内存分配:intern 字符串缓存和静态变量从永久代转移到元空间。 JIT 编译器优化:通过逃逸分析实现对象分配优化。
年前发现这本宝贝书,这本书会从运行时的内存结构来讲 JVM,每个结构讲的比网上的博客或者周志明的那本经典要细一些。很适合想入门或者想深入一点学习 JVM 的宝子。还没看完,希望再花两个月时间看完吧,弥补 JVM 这 一块的空白。目前已购一本纸质书,应该白嫖这么久,应该交交学费了😁
现在面试越来越卷了,Jvm作为面试必问的一个知识点,掌握这个技能已经是必不可少了。尚硅谷不仅有各种各样的学习视频,如今还有了电子书,这种方式真的挺好的,学习过程更轻松更方便,随时随地打开手机都能学习,内容讲解通俗易懂,深入浅出,大赞。