对象什么时候可以被垃圾器回收
在学习相关内容之前我们要明白两个问题,我们为什么要垃圾回收?回收哪里的垃圾呢?
垃圾回收主要指的是堆中的对象,堆是一个共享区域,我们创建的对象和数组,都存储在当前位置,但是我们不能无限的创建对象,也不是所有的对象都需要一直存在,如果不进行垃圾回收,那内存迟早会被耗尽的
简单一句就是:如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收。
如果要定位什么是垃圾,有两种方式来确定,第一个是引用计数法,第二个是可达性分析算法
引用计数法
可达性分析算法
哪些对象可以作为 GC Root ?
JVM 垃圾回收算法有哪些?
标记清除算法
复制算法
标记整理算法
JVM中的分代回收
工作机制
MinorGC、 Mixed GC 、 FullGC的区别
总结
JVM有哪些垃圾回收器?
在jvm中,实现了多种垃圾收集器,包括:
串行垃圾收集器
并行垃圾收集器
CMS(并发)垃圾收集器
G1垃圾收集器
Young Collection(年轻代垃圾回收)
g1里面新生代的内存占比不是固定的,在5%到6%进行调整
Young Collection + Concurrent Mark (年轻代垃圾回收+并发标记)
因为存活对象少,性价比高,可以释放更多内存,所以会挑出回收价值比较高的老年代和eden区和幸存者区进行垃圾回收
Mixed Collection (混合垃圾回收)
当完成了一次混合收集之后,可能还会进行多次混合收集,因为暂停时间有限。把剩下的老年代都重新标记,然后逐渐释放内存。然后又回到新一轮的Young Collection(年轻代垃圾回收)。
当然如果一个区域装不下,会存储到一个巨型对象中,如果一块区域不够的话,会分配一块连续的区域给巨型对象
总结
强引用、软引用、弱引用、虚引用的区别
在垃圾回收的时候,不同的引用,垃圾回收的情况是不一样的
强引用,即使出现了内存不足,出现了oom异常也不会回收强引用对象,只有gcroot找不到该对象才有可能垃圾回收
软引用,一开始并不会对user垃圾回收,只有在第一次回收之后,仍然内存不足才会回收
主要是根据handler来释放外部资源,比如现在user1,2都已经被垃圾回收了,但是这俩对象只是释放了java的堆内存的内部资源,但是他们在使用过程中,可能会使用一些外部资源,这些资源既不是java占用的,也不在java的内存,有可能使用的是直接内存。
那这些内存什么时候释放呢,他们必须要等java对象释放之后,才能去释放这些外部的资源对象,所以我们需要把这些资源放到引用对象队列中,先记录哪些对象被回收了,然后找哪些队列就行了。如图假如xy关联的对象已经被回收了,我们就应该把xy关联的对象回收掉,这个专业释放的线程就是Reference Handler,他就从引用队列中不断的把虚引用对象xy取出来,然后把他们占用的外部内存释放掉。
总结