其他文章:
面试被问到.class文件结构,赶紧背这几条!
如何判断对象是否死亡
-
引用计数法
- 每当一个地方引用它,就加一。引用失效,就减一。
- 缺点:无法避免循环引用。
-
可达性分析算法
- 对象与GCroot没有任何路径相连证明对象不可用。
-
可作为gc root的对象包括下面几种
- 虚拟机栈中引用的对象
- 本地方法栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 所有被同步锁持有的对象?
简单的介绍一下强引用、软引用、弱引用、虚引用(虚引用与软引用和弱引用的区别、使用软引用能带来的好处)
-
强引用
- 宁可out of memory,gc也不会回收它。
-
软引用
- 内存足够就不回收,内存不够就回收。可用来实现内存敏感的高速缓存。
-
弱引用
- 不管内存够不够,发现了就回收。
-
虚引用
- 和没有引用一样,任何时候都可能被回收,主要用来跟踪对象被垃圾回收的活动。
宣告对象死亡需要经历两次标记
- 不可达算法判断不可达后,第一次标记。
- 被标记的对象经过“是否有必要执行finalize方法”筛选
- 被筛选出的对象第二次标记,放在一个队列中,除非重新被引用,否则就会被真的回收。?怎么判断重新被引用?
如何判断一个常量是废弃常量
- jdk1.7前,运行时常量池包含字符串常量池,在方法区,对应永久代。
- jdk1.7后,字符串常量池在堆,运行时常量池还在方法区,对应永久代。
- jdk1.8后,字符串常量池还在堆,运行时常量池在方法区,对应元空间。
- 当没有任何对象引用常量,就说明常量可回收了。
如何判断一个类是无用的类
- 所有实例都已经被回收,堆中没有该类的实例。
- 加载该类的classLoader已经被回收
- 该类对应的java.lang.class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
垃圾收集算法
-
标记-清除算法
- 标出来的留着。剩下的回收。
- 效率不高,会导致内存空间不连续。
-
标记-复制算法
- 一半一半的使用内存空间,把左边存活的都挪到右边,然后把左边清空。
-
标记-整理算法
- 把留下的挨个排好,剩下的内存区域清空。针对老年代。
-
分代收集算法
- 分成新生代老生代选择不同算法。
HotSpot 为什么要分为新生代和老年代?
针对不同代的特点选择不同的回收算法。
垃圾回收器
-
serial
- 仅使用一个线程去收集。
- 收集的时候暂停其他所有工作线程。
- 新生代标记复制,老年代标记整理。
- 没有线程交互的开销,简单高效。
-
parnew
- 多线程版本的serial。
- 收集的时候暂停其他所有工作线程。
- 新生代标记复制,老年代标记整理。
-
parallel scanvage
- 和parnew几乎一样
- 关注吞吐量:cpu中用于运行用户代码时间与总消耗时间的比值。
- serial old
- parallel old
-
cms
- concurrent mark sweep 追求最短停顿时间,基本实现垃圾收集线程和用户线程同时工作。
-
标记-清除
- 初始标记:极短。暂停所有线程,标记可达对象对象。
- 并发标记:长。开启用户线程,记录可达对象和用户线程这段时间发生的引用更新。
- 重新标记:短。暂停所有线程。处理并发标记期间的引用更新。
- 并发清除:开启用户线程,清扫未标记的区域。?并发清除阶段发生的引用更新怎么办
-
g1收集器
- 针对多核大内存机器,停顿低吞吐高。
- 充分利用多核,和用户线程并行。
- 分代
- 整体看标记整理,部分看标记复制。
- 停顿时间可预测
- 维护优先列表,根据收集时间,优先选择回收价值最大的region回收。名字garbage first的由来。
-
zgc收集器
- 标记-复制算法,停顿时间更少。
分配担保机制?
- 标记-复制算法,停顿时间更少。
分区与GC
在jdk7前,堆内存被分为新生代、老生代、永久代三个区域。
jdk8之后永久代被彻底移除了,取而代之的是元空间。
新生代分为eden区,s0(from),s1(to)区。分配比例是8:1:1,可通过参数动态调整。
对象首先在eden区分配(如果太大就直接在老年代分配)。
当新生代空间不够时,发起minorGC。
在一次新生代垃圾回收后,如果对象还存活,年龄+1并进入survivor区,当年龄达到阈值(有的默认15,为什么是15,因为记录年龄的字段只有4位,CMS默认6)会进入老生代。
经过一次minorGC后,eden区和from区已经被清空,to区可能有对象存活,然后交换from和to。等to区被填满,所有对象移动到老生代中。
动态年龄计算:hotspot遍历所有对象,按照年龄大小对其所占用的大小进行累计,累计到survivor区的一半时,取这个年龄MaxTenuringThreshold中更小的值作为新的晋升年龄。
fullGC:当统计数据说youngGC之前晋升的平均大小比目前oldGen剩余空间大,则会触发FullGC,收集整个java堆和方法区。
全部评论
(1) 回帖