GC是垃圾收集的意思(Garbage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供了GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
JVM垃圾回收算法如下:
1. 标记-清除算法(Mark and Sweep)
首先从根对象开始标记所有可达对象,然后清除所有未被标记的对象。缺点是会产生大量碎片空间。
public class MarkSweepGarbageCollector {
private boolean[] marked;
public MarkSweepGarbageCollector(int size) {
marked = new boolean[size];
}
public void mark(int address) {
marked[address] = true;
}
public void sweep() {
for (int address = 0; address < marked.length; address++) {
if (!marked[address]) {
// 假设有一个memory对象来管理内存,这里是清除未标记的内存
// memory.free(address);
System.out.println("清除了地址:" + address);
}
}
// 清除标记数组
// marked = new boolean[marked.length];
}
// 示例方法,用于模拟对象创建,实际应用中这会触发GC
public void simulateObjectCreation() {
// 假设有一个memory对象来分配内存
int address = memory.allocate(10); // 分配了10个内存单元
mark(address); // 标记这块内存,避免被清除
}
public static void main(String[] args) {
MarkSweepGarbageCollector gc = new MarkSweepGarbageCollector(100);
gc.simulateObjectCreation();
gc.sweep(); // 执行垃圾回收
}
}
2. 复制算法(Copying)
将堆内存分为两个相等的区域,每次只使用其中一个区域。当一个区域满了之后,将存活的对象复制到另一个区域,并清除已经复制的对象。优点是不会产生碎片空间,缺点是浪费一半的内存空间。
void copying() {
copy(); // 复制阶段
}
void copy() {
// 复制过程
}
3. 标记-整理算法(Mark and Compact)
首先从根对象开始标记所有可达对象,然后将存活的对象向一端移动,并清除移动后的边界以外的内存。优点是不会产生碎片空间,缺点是需要移动对象,性能较差。
void markCompact() {
mark(); // 标记阶段
compact(); // 整理阶段
}
void mark() {
// 标记过程
}
void compact() {
// 整理过程
}
4. 分代算法(Generational)
将堆内存分为新生代和老年代,新生代一般使用复制算法,老年代一般使用标记-整理算法。根据对象的生命周期将内存划分为多个区域,根据各个区域的特点使用不同的垃圾回收算法,以提高性能。
void generationalCollection() {
if (youngGen()) {
// 新生代算法
} else {
oldGen(); // 老年代算法
}
}
boolean youngGen() {
// 新生代判断
}
void oldGen() {
// 老年代算法
}