垃圾回收相关概念
2020-09-29
System.gc()的理解 #
- 在默认情况下,通过System.gc()或者Runtime.getRuntime().gc()的调用会显示触发Full GC,但是该方法可能不是立刻就执行。
内存溢出 #
- 产生原因:没有空闲内存,并且垃圾收集器也无法提供更多内存。
内存泄漏 #
- 严格定义:对象不再被程序使用了,但是GC又不能回收他们的情况(仍然存在引用链)。
- 宽泛定义:一些不太好的实践会导致对象的生命周期变得很长,甚至导致OOM,也叫宽泛意义上的内存泄漏。
安全点 #
- 程序执行时并非在所有的地方都能停下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为“安全点”(safepoint)。
- 如何在GC发生时,检测所有的程序都跑到最近的安全点停顿下来了呢 –> 主动式中断:设置一个中断标志,各个线程运行到safe point的时候主动轮询这个标志,如果中断标志为真,则将自己进行中断挂起。
安全区域 #
- 指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始GC都是安全的。
- 可以应对处于sleep或者blocked状态的线程,这时候线程无法响应jvm的中断请求,“走”到安全点去中断挂起。
- 当程序运行到safe region的代码时,首先标识已经进入了safe region,如果这段时间发生了gc,jvm会忽略标识为safe region状态的线程。
- 当线程即将离开safe region时,会检测jvm是否已经完成了gc,如果完成了,则继续运行,否则线程必须等待直到收到可以安全离开safe region的信号为止。
引用 #
-
强引用:类似“Object object=new Object()”这类的引用,只要强引用还存在,就永不回收。
-
软引用:内存不足才回收。
-
弱引用:发现即回收。
-
虚引用:对象回收跟踪。
- 如果一个对象仅持有虚引用,那么它和没有引用几乎是一样的,随时都可能被垃圾回收器回收。
- 它不能单独使用,也无法通过虚引用来获取被引用的对象。当试图通过虚引用的get方法来获取对象时,总是null。
- 为一个对象设置虚引用关联的唯一目的就是能够在这个对象被收集器回收时收到一个系统通知。
- 虚引用必须和引用队列一起使用。虚引用在创建时必须提供一个引用队列作为参数。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象后,将这个虚引用加入引用队列,以通知引用程序对象的回收情况。
- 由于虚引用可以跟踪对象的回收时间,因此,也可以将一些资源释放操作放置在虚引用中执行和记录。
//声明强引用
Object obj=new Object();
//声明软引用
SoftReference<Object> sf=new SoftReference<Object>(new Object());
//声明弱引用
WeakReference<Object> wr=new WeakReference<Object>(new Object());
//虚引用
Object obj=new Object();
ReferenceQueue<Object> rq=new ReferenceQueue<>();
PhantomReference<Object> pr=new PhantomReference<>(obj,rq);
评估性能指标 #
- 吞吐量:运行用户代码时间占总运行时间的比例。
- 垃圾收集开销:吞吐量的补数,垃圾收集所用时间与总运行时间的比例。
- 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。
- 收集频率:相对于应用程序的执行,收集操作发生的频率。
- 内存占用:Java堆区所占的内存大小。
- 快速:一个对象从诞生到被回收所经历的时间。