1.哪些区域需要垃圾回收
栈是线程级别的在线程结束时就释放了。
接下来关注进程级别的:
方法区:主要保存类信息,常量,静态变量等,占用的空间相对稳定。
垃圾回收主要是堆
2.垃圾回收策略要考虑哪些方面
策略未必能完全落地。
a.回收的多-速度慢
b.回收的快-回收的少
c.回收哪些内容
直接想法:对象的引用计数为0。遇到的问题:不好解决循环引用的问题。
实际:垃圾收集器会回收GC Root不可达的对象
3.对象的生命周期
4.对象的引用
不同类型的引用,在垃圾收集方面的行为不同。
强引用
强引用是Java中最常见的引用类型。当一个对象被强引用变量引用时,无论任何情况,垃圾收集器都不会回收这个对象。即使在内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误,使程序异常终止,也不会回收这种对象。在Java中,我们平常最常见的就是强引用,例如:
String str = new String("Hello");
在这个例子中,`str`就是一个强引用。只有当`str`不再引用"Hello"(例如,`str = null`)时,"Hello"对象才可能被垃圾收集器回收。
软引用 SoftReference
只有当JVM内存不足时,垃圾收集器才会清除该对象。这使得它们对于缓存非常有用,因为只要内存充足,它们就会保留其值,并在其他地方需要内存时释放它们。
SoftReference<String> softReference = new SoftReference<>("Hello");
当持有时间过长没有使用的时候,也会回收。一些图片缓存会使用软引用。
使用场景:多用于处理占用内存大的,生命周期长的,使用不太频繁的对象。
优势:避免重复创建,提升内存使用效率的优化技术。
弊端:没被回收时,占用内存大,影响程序运行效率。
弱引用 WeakReference
使对象更易被回收。
只要垃圾收集器确定对象是弱可达的(也就是说,只能通过遍历弱引用来达到),就会清除该对象。这使得它们对于应该在其键不再在其他地方使用时自动删除其条目的映射非常有用。
使用场景:用于不容易被回收的情况。实际使用场景狭窄,较少用到。
虚引用 PhantomReference
PhantomReference是一种引用类型,只有在调用了finalize方法并且对象不再使用后,垃圾收集器才会清除该对象。这使得它们对于以比Java终结机制更灵活的方式安排死前清理操作非常有用。
使用场景:较少,主要辅助finalize的使用。
finalize方法
可不看。从Java 9开始,finalize方法已经被标记为deprecated,也就是不推荐使用。
是Java中Object类的一个方法,它会在垃圾收集器决定回收对象之前被调用。这个方法主要用于执行清理操作,比如释放非内存资源。
当垃圾收集器准备回收一个对象时,如果发现这个对象的类覆盖了finalize方法,那么垃圾收集器会将这个对象添加到一个名为finalization queue的队列中,并在某个时刻调用这个对象的finalize方法。
需要注意的是,finalize方法并不是一个可靠的资源清理手段。因为垃圾收集器的运行时机是不确定的,所以finalize方法的调用时机也是不确定的。此外,如果在finalize方法中出现异常,异常不会被捕获,也不会影响垃圾收集器的运行,这可能会导致资源无法被正确清理。 因此,从Java 9开始,finalize方法已经被标记为deprecated,也就是不推荐使用。对于需要清理的资源,推荐使用try-with-resources语句或者显式的close方法进行清理。
ReferenceQueue
提供的对要回收对象操作的可能性。
用于接收已经被垃圾收集器确定为可回收的对象的引用。当垃圾收集器决定回收一个对象,且该对象关联了一个ReferenceQueue,那么这个对象的引用就会被加入到这个ReferenceQueue中
ReferenceQueue常与SoftReference,WeakReference和PhantomReference一起使用。当创建这些引用类型时,可以选择传入一个ReferenceQueue。
当垃圾收集器决定回收这些引用所指向的对象时,这些引用就会被加入到它们关联的ReferenceQueue中。
这样,我们就可以通过检查ReferenceQueue来知道哪些对象已经被垃圾收集器决定回收,来做一些相应的处理。这对于清理一些资源,如关闭文件句柄,网络连接等非常有用。