### Sun JVM原理与内存管理
#### 一、Sun JDK 1.6 GC (Garbage Collector)
Sun JDK 1.6 的垃圾收集器(GC)是其内存管理的关键组成部分,它负责自动地回收不再使用的对象所占用的内存。本文将详细介绍Sun JDK 1.6 GC的工作原理、内存管理机制以及调优技巧。
#### 二、为什么学习GC?
- **性能瓶颈**:随着应用规模的增长,GC可能成为限制应用性能和并发能力的主要因素之一。
- **避免OOM**:合理使用GC可以有效防止出现“Out of Memory Error”(OOM)错误。
- **提高应用效率**:通过了解GC的工作原理,开发者可以更好地优化应用程序,减少内存消耗。
#### 三、内存结构
- **PC 寄存器**:用于存储当前线程正在执行的方法的指令地址。
- **局部变量区**:存放方法参数和局部变量。
- **操作数栈**:用于支持虚拟机中的字节码指令执行。
- **栈帧**:代表一个线程执行的方法。
- **JVM 方法栈**:存储每个线程的栈帧。
- **JVM 堆**:存储所有类实例和数组。
- **本地方法栈**:用于存储本地方法调用的栈帧。
#### 四、内存分配
1. **堆上分配**:
- 大多数对象都将在新生代的 Eden 区分配。
- 特殊情况下直接在 Old 区分配,如大对象或长时间存活的对象。
- TLAB (Thread Local Allocation Buffer) 是一种优化技术,允许每个线程拥有自己的缓冲区,从而加快分配速度。
2. **栈上分配**:
- 适用于原子类型和某些局部变量。
- 使用逃逸分析等技术判断对象是否可以放在栈上,以减少垃圾回收的压力。
3. **堆外分配**:
- `DirectByteBuffer` 直接分配堆外内存。
- `Unsafe.allocateMemory` 提供了一种不推荐的直接内存分配方式。
#### 五、内存回收
- **Hotspot 认为没有引用的对象是 dead 的**:
- 通过可达性分析确定哪些对象仍然被引用,未被引用的对象被认为是 dead 的。
- **引用类型**:
- **Strong**:默认引用类型,如 `Object obj = new Object();`。
- **Soft**:软引用,当系统即将发生内存溢出时会被回收。
- **Weak**:弱引用,在下一次GC时就会被回收。
- **Phantom**:虚引用,仅用于跟踪对象被垃圾回收的时间点。
#### 六、分代管理
- **Sun Hotspot 对 JVM 堆采用分代管理**:
- **新生代** (Young Generation):包含 Eden 和 Survivor 区域 (S0/S1)。
- **老年代** (Old Generation):长期存活的对象将被转移到这里。
- **分代策略**:利用年轻代和老年代的不同特点来优化内存回收。
#### 七、不同GC算法
1. **串行GC** (Serial Copying):
- 单线程进行垃圾回收。
- 在 client 模式下默认使用。
- 适合于单核处理器或轻负载的应用场景。
2. **并行回收GC** (Parallel Scavenge):
- 多线程进行垃圾回收。
- 侧重于吞吐量最大化。
- 适合于多核处理器和高负载的应用场景。
3. **并行GC** (ParNew):
- 新生代的并行垃圾回收。
- 可以与其他 GC 算法结合使用。
- 支持自定义垃圾回收频率和暂停时间。
#### 八、案例分析
- **示例代码**:
```java
public class SerialGCDemo {
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[1024 * 1024 * 2];
byte[] bytes2 = new byte[1024 * 1024 * 2];
byte[] bytes3 = new byte[1024 * 1024 * 2];
Thread.sleep(3000);
byte[] bytes4 = new byte[1024 * 1024 * 4];
Thread.sleep(3000);
}
}
```
- **命令行参数**:
- `-Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC`:设置初始堆大小、最大堆大小、新生代大小,并指定使用串行GC。
- `-Xms20M -Xmx20M -Xmn10M -XX:PretenureSizeThreshold=3145728 -XX:+UseSerialGC`:设置对象大小超过3MB时直接进入老年代。
#### 九、调优
- **调整堆大小**:
- `-Xms` 设置初始堆大小。
- `-Xmx` 设置最大堆大小。
- `-Xmn` 设置新生代大小。
- `-XX:SurvivorRatio` 控制 Eden 和 Survivor 区的比例。
- **调整GC行为**:
- `-XX:+UseParallelGC` 启用并行GC。
- `-XX:+UseConcMarkSweepGC` 启用并发标记-清除算法。
- `-XX:SoftRefLRUPolicyMSPerMB` 设置 Soft 引用的回收策略。
#### 十、结论
理解 Sun JDK 1.6 的内存管理和 GC 工作原理对于开发高效稳定的应用至关重要。通过合理的内存分配策略和恰当的 GC 调整,可以显著提高应用程序的性能和稳定性。