JVM的内存回收及常见算法小结
什么是垃圾回收?
垃圾回收是指通过某些算法与过程,自动回收程序中不再被使用且占用内存的变量及对象等资源。JVM内置了垃圾回收机制,来管理Java程序使用的内存。垃圾回收可以帮助程序员有效地管理内存,减少内存泄露等问题。
JVM内存模型
JVM将内存分为三个区域:程序计数器、Java栈与Java堆。
- 程序计数器:记录当前线程运行的字节码指令地址。
- Java栈:线程私有,用于存放局部变量表、操作数栈、动态链接、方法出口等信息。
- Java堆:所有线程共享,用于存放对象实例及数组等。
常用垃圾回收算法
1. 标记-清除(Mark-Sweep)
标记-清除算法依次标记所有活动对象,并在标记完成后清除所有没有被标记的对象。该算法会导致堆内存中产生大量的碎片,从而影响内存的分配。
示例:
public class MarkSweepGC {
private static class TestObject {
private byte[] data = new byte[1024 * 1024]; // 1 MB
}
public static void main(String[] args) {
List<TestObject> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new TestObject());
}
// do something
list.clear();
System.gc();
}
}
2. 复制(Copy)
复制算法将可用内存分为两部分,每次只使用其中的一部分。当一部分的内存空间使用完后,将存活的对象复制到另一个内存中,然后清空当前内存空间。该算法可以避免碎片问题。
示例:
public class CopyGC {
private static class TestObject {
private byte[] data = new byte[1024 * 1024]; // 1 MB
}
public static void main(String[] args) {
List<TestObject> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new TestObject());
}
// do something
list.clear();
System.gc();
}
}
3. 标记-复制(Mark-Compact)
标记-复制算法结合了标记-清除算法和复制算法的优点,它先标记所有存活对象,之后将存活对象都移动到一端,然后清除边界外的所有对象,从而避免了碎片化问题。
示例:
public class MarkCompactGC {
private static class TestObject {
private byte[] data = new byte[1024 * 1024]; // 1 MB
}
public static void main(String[] args) {
List<TestObject> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new TestObject());
}
// do something
list.clear();
System.gc();
}
}
垃圾回收机制类型
JVM中有两种类型的垃圾回收器:串行垃圾回收器和并行垃圾回收器。
- 串行垃圾回收器:单线程工作,适用于单CPU环境,目标是能够最大化运行内存的吞吐量。
- 并行垃圾回收器:多线程工作,适用于多CPU环境,目标是尽可能缩短GC暂停时间,但是会牺牲一些吞吐量。
总结
以上是JVM的内存回收及常见算法的小结。在实际开发中,需要根据项目的特点选择合适的垃圾回收器与算法,并监控GC日志及内存占用情况,及时进行优化。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JVM的内存回收及常见算法小结 - Python技术站