1.如何判断对象可以回收
1.1 引用计数法
A引用B时计数加1,当不引用时计数减一,当计数为0时,则该对象被垃圾回收,弊端,当A,B两个对象循环引用时,不可以被垃圾回收掉.容易造成内存泄露。
1.2 可达性分析算法
根对象:肯定不能当成垃圾回收的对象。
扫描堆中的对象,看是否能沿着根对象为起点的引用链找到该对象,找不到,表示可以回收。
1.3 四种引用
强引用:所有的跟对象都不通过强引用该对象,才会被回收掉。
软引用:当内存不足时,会被回收掉。
弱引用:只要发生垃圾回收,都会被回收掉。
虚引用:直接内存不在jvm中,没办法被垃圾回收,因此虚引用关联引用队列,当ByteBuffer被回收时,虚引用直接进入引用队列,本地方法随即根据引用队列中的相关信息调用unsafe方法清楚本地的内存。
终结器引用:无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队,再由finalize线程通过终结器引用找到被引用对象,并调用他的finalize方法,第二次GC时才能回收被引用对象。
2.垃圾回收算法
标记清除:将不被引用的对象标记为垃圾,然后清除,缺点:内存碎片化
标记整理:将不被引用的对象标记为垃圾,然后清除并整理,缺点:效率低
复制:将内存分为两片,将不被引用的对象标记为垃圾,把被引用的对象复制到一个空内存,然后清除第一个内存,然后交互两个内存,缺点:占用双倍的内存空间
3.分代垃圾回收
3.1 新生代
3.2 老年代
当老年代空间不足时,会先尝试触发 minor gc ,如果空间仍不足,那么触发 full gc , STW 的时间更长
4.垃圾回收器
4.1 串行
单线程
适用场景:堆内存较小,适合个人电脑
4.2 吞吐量优先
多线程
适用场景:堆内存较大,多核CPU
在单位时间内STW时间最短
4.3 响应时间优先
多线程
适用场景:堆内存较大,多核CPU
尽可能让单次STW时间最短