上传者: wangwang00001
|
上传时间: 2025-11-17 14:02:37
|
文件大小: 3.11MB
|
文件类型: PDF
虚拟机学习笔记
Java 虚拟机(JVM)是 Java 语言的 runtime 环境,负责加载、验证、执行 Java 字节码。以下是 JVM 相关知识点的总结。
1. 运行时数据区域
JVM 的运行时数据区域主要包括:
* 堆(Heap):用于存储对象、数组等内存,GC 管理和回收。
* 方法区(Method Area):存储被 JVM 加载的类信息、运行时常量池、JIT 编译后的 Code Cache 等信息。
* 直接内存(Direct Memory):用于 NIO 的缓冲区分配,避免在系统内存与 JVM 堆内存之间拷贝的开销。
* 线程私有内存(Thread Private Memory):包括程序计数器、JVM 栈、本地方法栈等。
2. 对象的内存布局
对象的内存布局主要包括:
* 对象头(Object Header):记录对象的运行时信息,如 hashCode、GC 分代年龄、锁状态等。
* Class Pointer:指向所属的类信息数组长度(可选,对象为数组)。
* 对象数据(Object Data):各种字段的值,按宽度分类紧邻存储。
* 对齐填充(Alignment Padding):内存对齐为 1 个字长整数倍,减少 CPU 总线周期。
3. 内存溢出
内存溢出(OutOfMemoryError)是指 JVM 无法分配对象所需内存时抛出的异常。解决方法包括:
* 调整堆大小:使用 -Xms 和 -Xmx 选项调整堆的初始大小和最大大小。
* 找出无法被回收的大对象:使用 Eclipse MAT 分析堆转储文件,定位无法被回收的大对象,找出其 GC Root 引用路径。
* 优化代码:使用 null 显式赋值、虚引用等方式及时回收大对象,减少大对象的生命周期,检查数据结构使用是否合理等。
4. JVM 对象创建
JVM 对象创建过程包括:
* 类加载:类加载完毕后,其对象所需内存大小是确定的。
* 对象分配:堆内存由多线程共享,使用 CAS 乐观锁争夺内存,故线程创建时在堆内存为其分配私有的分配缓冲区(TLAB)。
* 零值初始化:对象的堆内存、设置对象头信息、执行构造函数。
5. JVM 堆内存分配
JVM 堆内存分配流程包括:
* TLAB 剩余空间不足以分配新对象,但又小于最大浪费空间阈值时,才会加锁创建新的 TLAB。
* 对象头信息:记录对象的运行时信息,如 hashCode、GC 分代年龄、锁状态等。
JVM 是 Java 语言的 runtime 环境,负责加载、验证、执行 Java 字节码。 JVM 的运行时数据区域包括堆、方法区、直接内存、线程私有内存等。对象的内存布局包括对象头、Class Pointer、对象数据、对齐填充等。内存溢出可以通过调整堆大小、找出无法被回收的大对象、优化代码等方式解决。