指标
吞吐量:运行用户代码的时间占总运行时间的比例。- (总运行时间 = 程序的运行时间 + 内存回收的时间)
垃圾收集开销:吞吐量的补数,垃圾收集所用时间与总运行时间的比例。
暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。收集频率:相对于应用程序的执行,收集操作发生的频率。
内存占用:Java堆区所占的内存大小。快速:一个对象从诞生到被回收所经历的时间。
吞吐量:运行用户代码的时间占总运行时间的比例。
垃圾收集开销:吞吐量的补数,垃圾收集所用时间与总运行时间的比例。
暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。
收集频率:相对于应用程序的执行,收集操作发生的频率。
内存占用:Java堆区所占的内存大小。
快速:一个对象从诞生到被回收所经历的时间。
垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的JVM来实现。
由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本。
从不同角度分析垃圾收集器,可以将GC分为不同的类型。
我们希望能描述这样一类对象:当内存空间还足够时,则能保留在内存中;如果内存空间在进行垃圾收集后还是很紧张,则可以抛弃这些对象。
在JDK1.2版之后,Java对引用的概念进行了扩充,将引用分为:
这4种引用强度依次逐渐减弱。
除强引用外,其他3种引用均可以在java.lang.ref包中找到它们的身影。如下图,显示了这3种引用类型对应的类,开发人员可以在应用程序中直接使用它们。

程序执行时并非在所有地方都能停顿下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为“安全点(Safepoint)”。
Safe Point的选择很重要,如果太少可能导致GC等待的时间太长,如果太频繁可能导致运行时的性能问题。大部分指令的执行时间都非常短暂,通常会根据“是否具有让程序长时间执行的特征”为标准。比如:选择一些执行时间较长的指令作为Safe Point,如方法调用、循环跳转和异常跳转等。
在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理器上运行
并发不是真正意义上的“同时进行”,只是CPU把一个时间段划分成几个时间片段(时间区间),然后在这几个时间区间之间来回切换。由于CPU处理的速度非常快,只要时间间隔处理得当,即可让用户感觉是多个应用程序同时在进行

JVM-043-垃圾回收-相关概念的概述-内存溢出与内存泄漏
内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也是引发程序崩溃的罪魁祸首之一。
由于GC一直在发展,所以一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现OOM的情况。
大多数情况下,GC会进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的Full GC操作,这时候会回收大量的内存,供应用程序继续使用。
Javadoc中对OutofMemoryError的解释是,没有空闲内存,并且垃圾收集器也无法提供更多内存。
JVM-042-垃圾回收-相关概念的概述-System.gc()的理解
在默认情况下,通过System.gc()或者Runtime.getRuntime().gc() 的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。
然而System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用(不能确保立即生效)
JVM实现者可以通过System.gc() 调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基本测试,我们可以在运行之间调用System.gc()。
没有最好的算法,只有最合适的算法
前面所有这些算法中,并没有一种算法可以完全替代其他算法,它们都具有自己独特的优势和特点。分代收集算法应运而生。分代的思想被现有的虚拟机广泛使用。几乎所有的垃圾回收器都区分新生代和老年代。