GC算法与种类

本文主要介绍了Java中的垃圾收集(GC)机制。阐述了GC的对象是堆空间和永久区,介绍了引用计数法、标记清除、标记压缩、复制算法等GC算法,还提及分代思想、可触及性等概念。同时说明了Stop - The - World现象及危害,建议避免使用finalize()方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Garbage Collection 垃圾收集

JAVA中GC的对象是堆空间和永久区

GC算法
1 引用计数法 --python
对象一旦被引用标记+1,引用失效-1,标记为0的对象不能使用
性能差,无法处理循环引用
2 标记清除 --java
从根节点开始不可达的点标记清除
3 标记压缩 --java
优化的标记清除,将存活对象压缩到内存的一端,清理其他所有空间
适用于存活对象较多场合,寻址更快,减少空间碎片,同时空闲内存是连续 的,但搬运对象会耗时间
4 复制算法 --java 新生代
高效,将内存分为两块,每次只用一块,回收时将存活对象复制到未使用的内存块,再清除原内存块中所有对象,互换角色

分代思想
根据存活周期,短命对象为新生代,长命对象为老年代
少量对象存活适合复制算法,大量适合标记清除或标记压缩

可触及性

可触及的
从根节点可以触及到这个对象
可复活的
一旦所有引用被释放,就是可复活状态
因为在finalize()中可能复活该对象
不可触及的
在finalize()后,可能会进入不可触及状态
不可触及的对象不可能复活
可以回收

public class CanReliveObj {
	public static CanReliveObj obj;
	@Override
	protected void finalize() throws Throwable {
	    super.finalize();
	    System.out.println("CanReliveObj finalize called");
	    obj=this;
	}
	@Override
	public String toString(){
	    return "I am CanReliveObj";
	}
	CanReliveObj finalize called
	obj 可用
	第二次gc
	obj 是 null
	
	public static void main(String[] args) throws    InterruptedException{
		obj=new CanReliveObj();
		obj=null;   //可复活
		System.gc();
		Thread.sleep(1000);
		if(obj==null){
		    System.out.println("obj 是 null");
		}else{
		    System.out.println("obj 可用");
		}
		System.out.println("第二次gc");
		obj=null;    //不可复活
		System.gc();
		Thread.sleep(1000);
		if(obj==null){
		System.out.println("obj 是 null");
		}else{
		System.out.println("obj 可用");
		}
	}
}

经验:避免使用finalize(),操作不慎可能导致错误。
优先级低,何时被调用, 不确定
何时发生GC不确定
可以使用try-catch-finally来替代它


栈中引用的对象
方法区中静态成员或者常量引用的对象(全局对象)
JNI方法栈中引用对象

Stop-The-World
Java中一种全局暂停的现象
全局停顿,所有Java代码停止,native代码可以执行,但不能和JVM交互
多半由于GC引起
Dump线程
死锁检查
堆Dump

GC时为什么会有全局停顿?
类比在聚会时打扫房间,聚会时很乱,又有新的垃圾产生,房间永远打扫不干净,只有让大家停止活动了,才能将房间打扫干净。
危害
长时间服务停止,没有响应
遇到HA系统,可能引起主备切换,严重危害生产环境。

public static class PrintThread extends Thread{
	public static final long starttime=System.currentTimeMillis();
	@Override
	public void run(){
		try{
			while(true){
				long t=System.currentTimeMillis()-starttime;
				System.out.println("time:"+t);
				Thread.sleep(100);
			}
		}catch(Exception e){
			
		}
	}
}


public static class MyThread extends Thread{
	HashMap<Long,byte[]> map=new HashMap<Long,byte[]>();
	@Override
	public void run(){//工作线程
		try{
			while(true){
				if(map.size()*512/1024/1024>=450){//大于450M时清理内存
					System.out.println(“=====准备清理=====:"+map.size());
					map.clear();
				}
				
				for(int i=0;i<1024;i++){
					map.put(System.nanoTime(), new byte[512]);
				}
				Thread.sleep(1);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
-Xmx512M -Xms512M -XX:+UseSerialGC -Xloggc:gc.log -XX:+PrintGCDetails  -Xmn1m -XX:PretenureSizeThreshold=50 -XX:MaxTenuringThreshold=1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值