JVM 内存结构:
Java虚拟机的内存结构主要分为以下几个部分:
-
程序计数器(Program Counter Register):
- 用于记录线程执行的字节码指令的地址,是线程私有的。
-
Java虚拟机栈(Java Virtual Machine Stacks):
- 每个线程在执行Java方法时会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。是线程私有的。
-
本地方法栈(Native Method Stack):
- 与Java虚拟机栈类似,但是用于执行本地方法(即用其他语言编写的方法)。是线程私有的。
-
Java堆(Java Heap):
- 存放对象实例。Java堆是线程共享的,所有线程共同使用。垃圾回收主要发生在这个区域。
-
方法区(Method Area):
- 存放类的元数据信息、静态变量、常量等数据。是线程共享的。
-
运行时常量池(Runtime Constant Pool):
- 存放编译时生成的各种字面量和符号引用。是方法区的一部分。
-
直接内存(Direct Memory):
- 不是虚拟机运行时数据区的一部分,但也会被频繁使用。主要通过
NIO来使用,通过ByteBuffer等类分配直接内存。
- 不是虚拟机运行时数据区的一部分,但也会被频繁使用。主要通过
垃圾回收策略:
-
标记-清除(Mark and Sweep):
- 将内存分为两部分,标记出存活的对象,然后清除未被标记的对象。容易产生内存碎片。
-
复制(Copying):
- 将内存分为两块,一块用于存放存活对象,另一块用于清理。每次清理都将存活对象复制到另一块,然后清理整块空间。
-
标记-整理(Mark and Compact):
- 标记存活对象,然后将它们移动到内存的一端,然后清理掉边界以外的空间。解决了标记-清除的内存碎片问题。
-
分代收集(Generational Collection):
- 将堆分为新生代和老年代,新生代使用复制算法,老年代使用标记-整理或标记-清除算法。利用新生代对象的短命特性,提高回收效率。
垃圾回收算法:
-
标记-清除算法(Mark and Sweep):
- 标记出存活对象,然后清理未被标记的对象。缺点是产生内存碎片。
-
复制算法(Copying):
- 将内存分为两块,每次只使用其中一块。将存活对象复制到另一块,然后清理当前使用的块。适用于新生代的垃圾回收。
-
标记-整理算法(Mark and Compact):
- 标记存活对象,然后将它们移动到一端,然后清理边界以外的空间。解决了标记-清除的内存碎片问题。
-
分代收集算法(Generational Collection):
- 将堆分为新生代和老年代,新生代使用复制算法,老年代使用标记-整理或标记-清除算法。根据对象的存活时间不同,采用不同的回收策略。