jvm学习

作者: 放羊娃华振 | 来源:发表于2026-01-12 00:04 被阅读0次

目录

  1. JVM 概述
  2. 字节码指令详解
  3. Java 虚拟机参数详解
  4. JVM 性能调优工具
  5. JHSDB 工具详解
  6. 实践案例
  7. 总结

JVM 概述

Java 虚拟机(Java Virtual Machine,JVM)是 Java 程序运行的核心组件。它是一个抽象的计算机,具有指令集并使用虚拟机的实例来执行 Java 字节码。JVM 的主要特点包括:

  • 平台无关性:一次编写,到处运行
  • 内存管理:自动垃圾回收机制
  • 安全沙箱:限制代码执行权限
  • 动态加载:运行时动态加载类

JVM 内存结构

JVM 内存主要分为以下几个区域:

  • 方法区(Method Area):存储类信息、常量、静态变量等
  • 堆(Heap):存储对象实例和数组
  • 虚拟机栈(VM Stack):存储局部变量表、操作数栈等
  • 程序计数器(Program Counter Register):记录当前线程执行的字节码指令地址
  • 本地方法栈(Native Method Stack):为本地方法服务

字节码指令详解

Java 源代码经过编译后会生成字节码(bytecode),字节码是 JVM 的指令集。以下是常见的字节码指令分类:

1. 加载和存储指令

这些指令用于在局部变量表和操作数栈之间传输数据:

  • iload:将 int 类型的局部变量推送至栈顶
  • aload:将引用类型的局部变量推送至栈顶
  • istore:将栈顶的 int 值存入局部变量
  • astore:将栈顶的引用值存入局部变量

2. 运算指令

用于数值计算:

  • iadd:int 加法
  • isub:int 减法
  • imul:int 乘法
  • idiv:int 除法
  • iinc:int 自增

3. 类型转换指令

  • i2l:int 转 long
  • i2f:int 转 float
  • i2d:int 转 double
  • l2i:long 转 int

4. 对象创建和访问指令

  • new:创建对象
  • getfield:获取对象字段值
  • putfield:设置对象字段值
  • getstatic:获取静态字段值
  • putstatic:设置静态字段值

5. 方法调用和返回指令

  • invokevirtual:调用实例方法
  • invokestatic:调用静态方法
  • invokeinterface:调用接口方法
  • ireturn:返回 int 值
  • areturn:返回引用值

6. 控制转移指令

  • ifeq:当栈顶 int 值等于 0 时跳转
  • ifne:当栈顶 int 值不等于 0 时跳转
  • iflt:当栈顶 int 值小于 0 时跳转
  • ifge:当栈顶 int 值大于等于 0 时跳转
  • goto:无条件跳转

7. 异常处理指令

  • athrow:抛出异常

8. 同步指令

  • monitorenter:进入同步块
  • monitorexit:退出同步块

Java 虚拟机参数详解

Java 虚拟机提供了大量的启动参数来配置 JVM 的运行行为,主要分为以下几类:

1. 标准参数(Standard Options)

这些参数在所有 Java 实现中都必须支持:

  • -server:以服务器模式运行 JVM
  • -client:以客户端模式运行 JVM
  • -version:显示版本信息
  • -verbose:输出详细信息
  • -cp-classpath:指定类路径
  • -Dproperty=value:设置系统属性

2. 非标准参数(Non-Standard Options)

这些参数以 -X 开头:

  • -Xms<size>:设置堆的初始大小
  • -Xmx<size>:设置堆的最大大小
  • -Xss<size>:设置线程栈大小
  • -Xmn<size>:设置新生代大小
  • -Xprof:输出 CPU 配置文件数据

3. 高级参数(Advanced Options)

这些参数以 -XX 开头:

堆内存相关参数

  • -XX:NewRatio=<ratio>:设置老年代与新生代的比例
  • -XX:SurvivorRatio=<ratio>:设置 Eden 区与 Survivor 区的比例
  • -XX:MaxTenuringThreshold=<value>:设置对象晋升到老年代的年龄阈值
  • -XX:+UseSerialGC:使用串行垃圾收集器
  • -XX:+UseParallelGC:使用并行垃圾收集器
  • -XX:+UseConcMarkSweepGC:使用 CMS 垃圾收集器
  • -XX:+UseG1GC:使用 G1 垃圾收集器

性能调优相关参数

  • -XX:+PrintGCDetails:打印详细的 GC 信息
  • -XX:+PrintGCTimeStamps:打印 GC 时间戳
  • -XX:+PrintGCApplicationStoppedTime:打印 GC 暂停时间
  • -XX:+HeapDumpOnOutOfMemoryError:内存溢出时生成堆转储文件
  • -XX:HeapDumpPath=<path>:指定堆转储文件路径

4. 参数示例

java -Xms2g -Xmx4g -XX:NewRatio=1 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar myapp.jar

JVM 性能调优工具

JVM 提供了多种性能调优和诊断工具,帮助开发者分析和优化 Java 应用程序的性能。

1. jps(JVM Process Status Tool)

显示当前系统中所有 Java 进程的信息:

jps -l  # 显示主类完整路径
jps -v  # 显示 JVM 参数
jps -m  # 显示传递给主类的参数

2. jstat(JVM Statistics Monitoring Tool)

监控 JVM 统计信息:

jstat -gc <pid> 1000    # 每秒显示 GC 统计信息
jstat -gccapacity <pid> # 显示 GC 容量信息
jstat -class <pid>      # 显示类加载统计信息

3. jinfo(JVM Configuration Information Tool)

查看和修改 JVM 参数:

jinfo -flag <flag> <pid>     # 查看指定参数值
jinfo -flag +<flag> <pid>    # 启用参数
jinfo -flag -<flag> <pid>    # 禁用参数
jinfo -flags <pid>           # 显示所有参数

4. jstack(JVM Stack Trace Tool)

生成 Java 进程的堆栈跟踪:

jstack <pid>                 # 生成线程堆栈
jstack -l <pid>              # 包含锁信息

5. jmap(JVM Memory Map Tool)

生成堆内存映射信息:

jmap -heap <pid>             # 显示堆内存详细信息
jmap -histo <pid>            # 显示堆中对象统计信息
jmap -dump:format=b,file=<filename> <pid>  # 生成堆转储文件

JHSDB 工具详解

JHSDB(Java HotSpot Debugger)是 JDK 9+ 中引入的命令行调试工具,用于分析 JVM 进程的内部状态,特别是在 JVM 崩溃或挂起时。

1. 启动 JHSDB

jhsdb jstack --pid <pid>     # 生成线程堆栈
jhsdb clhsdb --pid <pid>     # 启动 CLHSDB(命令行 HSD)
jhsdb hsdb --pid <pid>       # 启动图形化 HSDB

2. 使用 CLHSDB

CLHSDB 提供了命令行界面来查看 JVM 内部信息:

# 查看内存布局
mem <address> <size>

# 查看对象
inspect <address>

# 查看 OOPMap
oopmap <thread>

# 查看符号表
symbols

# 查看类加载器
classloader

3. 查看 JVM 内存分配

通过 JHSDB 可以查看 JVM 中的具体内存分配情况:

# 查看堆内存使用情况
jhsdb jmap --heap --pid <pid>

# 查看具体的对象分布
jhsdb jmap --histo --pid <pid>

实践案例

案例 1:内存泄漏分析

  1. 使用 jmap -histo 查看对象统计信息
  2. 生成堆转储文件 jmap -dump
  3. 使用 JHSDB 分析内存使用情况

案例 2:GC 性能优化

  1. 监控 GC 行为:jstat -gc <pid> 1000
  2. 分析 GC 日志,识别频繁的 GC 事件
  3. 调整堆大小参数和 GC 算法

案例 3:死锁检测

  1. 使用 jstack 生成线程堆栈
  2. 分析线程状态,识别死锁情况
  3. 定位死锁代码位置

总结

JVM 是 Java 程序运行的基础,理解 JVM 的工作原理对于 Java 开发者至关重要。本文介绍了:

  1. JVM 基础概念:内存结构、运行机制
  2. 字节码指令:了解 Java 代码如何转换为 JVM 指令
  3. JVM 参数:配置 JVM 行为和性能调优
  4. 性能工具:jps、jstat、jinfo、jstack、jmap 的使用
  5. JHSDB 工具:深入分析 JVM 内部状态

掌握这些知识有助于:

  • 优化 Java 应用程序性能
  • 快速定位和解决内存问题
  • 提高系统的稳定性和可靠性
  • 更好地理解 Java 程序的运行机制

参考文章

哔哩哔哩老师讲的jvm:
https://www.bilibili.com/video/BV11S4y1W7dJ?p=4&spm_id_from=333.880.my_history.page.click&vd_source=09ca3e9049c99f913df3c91ce6d7564a

字节码指令:
https://cloud.tencent.com/developer/article/1333540

java的参数oracle官方文档:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

jvm 性能调优工具之 jinfo:
https://www.jianshu.com/p/8d8aef212b25

JHSDB-查看jvm中的内存具体分配
参考:https://www.jianshu.com/p/42cbfc44d70a

相关文章

网友评论

      本文标题:jvm学习

      本文链接:https://www.haomeiwen.com/subject/ofaenrtx.html