0. GC
GC 是垃圾收集的意思 ,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会 导致程序或系统的不稳定甚至崩溃, Java 提供 的 GC 功能可以自动监测对象是否超过作用域从 而达到自动回收内存的目的 ,Java 语言没有提供释放已分配内存的显示操作方法 。Java 程序员不 用担 心内 存管 理, 因为垃圾收集器会自动进行管理 。要请求垃圾收集 ,可以调用下面的方法 之一 :System.gc() 或Runtime.getRuntime().gc() ,但 JVM 可以屏蔽掉显示的垃圾回收调用 。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。在 Java 诞生初期,垃圾回收是 Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今 Java 的垃圾回收机制已经成为被诟病的东。移动智能终端用户通常觉得 iOS 的系统比 Android 系统有更好的用户体验,其中一个深层次的原因就在于 Android 系统中垃圾回收的不可预知性。
1. 如何确定垃圾
引用计数法:在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关联的引用,即他们的引用计数都不为 0,则说明对象不太可能再被用到,那么这个对象就是可回收对象。
可达性分析:为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots” 对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记过程。两次标记后仍然是可回收对象,则将面临回收。
2. 垃圾收集算法
标记清除:先标记,标记完毕之后再清除,效率不高,会产生碎片
复制算法:复制算法将可用内存按容量划分为相等的两部分,然后每次只使用其中的一块,当一块内存用完时,就将还存活的对象复制到第二块内存上,然后一次性清楚完第一块内存,再将第二块上的对象复制到第一块。
效率低,每次浪费一半内存。优化:不按照1:1分区。按照 8:1:1 分为 Eden 区和 survivor 区,就是上面谈到的 YGC. Eden区满则分配到servivor,servivor区满则通过分配担保机制分配到old。
标记整理:标记完毕之后,让所有存活的对象向一端移动。主要是为了解决标记-清除,产生大量内存碎片的问题
分代收集:将堆分为新生代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担
保,所以可以使用 标记-整理 或者 标记-清除。
3. 垃圾收集器有哪些? CMS 收集器与 G1 收集器的特点
并行收集器:串行收集器使用一个单独的线程进行收集, GC 时服务有停顿时间
串行收集器:次要回收中使用多线程来执行
CMS: 收集器是基于“标记—清除”算法实现的,经过多次标记才会被清除
G1: 从整体来看是基于“标记—整理”算法实现的收集器,从局部(两个 Region 之间)
上来看是基于“复制”算法实现的
标签:Java,收集器,对象,标记,回收,GC,垃圾 From: https://blog.51cto.com/u_15905340/5919338