如果确定对象已经死亡,我们又该如何回收这些垃圾呢
#3.4 垃圾回收算法不会非常详细的展开,常用的有标记清除,复制,标记整理和分代收集算法
#3.4.1 标记清除算法标记清除算法就是分为“标记”和“清除”两个阶段 。标记出所有需要回收的对象,标记结束后统一回收 。这个套路很简单,也存在不足,后续的算法都是根据这个基础来加以改进的 。
其实它就是把已死亡的对象标记为空闲内存,然后记录在一个空闲列表中,当我们需要new一个对象时,内存管理模块会从空闲列表中寻找空闲的内存来分给新的对象 。
不足的方面就是标记和清除的效率比较低下 。且这种做法会让内存中的碎片非常多 。这个导致了如果我们需要使用到较大的内存块时,无法分配到足够的连续内存 。比如下图
文章插图
此时可使用的内存块都是零零散散的,导致了刚刚提到的大内存对象问题
#3.4.2 复制算法为了解决效率问题,复制算法就出现了 。它将可用内存按容量划分成两等分,每次只使用其中的一块 。和survivor一样也是用from和to两个指针这样的玩法 。fromPlace存满了,就把存活的对象copy到另一块toPlace上,然后交换指针的内容 。这样就解决了碎片的问题 。
这个算法的代价就是把内存缩水了,这样堆内存的使用效率就会变得十分低下了
文章插图
不过它们分配的时候也不是按照1:1这样进行分配的,就类似于Eden和Survivor也不是等价分配是一个道理 。
#3.4.3 标记整理算法复制算法在对象存活率高的时候会有一定的效率问题,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存
文章插图
3.4.4 分代收集算法这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块 。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法 。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集 。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或者“标记-整理”算法来进行回收 。
说白了就是八仙过海各显神通,具体问题具体分析了而已 。
#3.5 (了解)各种各样的垃圾回收器HotSpot VM中的垃圾回收器,以及适用场景
文章插图
到jdk8为止,默认的垃圾收集器是Parallel Scavenge 和 Parallel Old
从jdk9开始,G1收集器成为默认的垃圾收集器 目前来看,G1回收器停顿时间最短而且没有明显缺点,非常适合Web应用 。在jdk8中测试Web应用,堆内存6G,新生代4.5G的情况下,Parallel Scavenge 回收新生代停顿长达1.5秒 。G1回收器回收同样大小的新生代只停顿0.2秒 。
#3.6 (了解)JVM的常用参数JVM的参数非常之多,这里只列举比较重要的几个,通过各种各样的搜索引擎也可以得知这些信息 。
含义
默认值
说明
-Xms
初始堆大小
物理内存的1/64(<1GB)
默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx
最大堆大小
物理内存的1/4(<1GB)
默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn
年轻代大小(1.4or later)
注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的 。整个堆大小=年轻代大小 + 老年代大小 + 持久代(永久代)大小.增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-XX:NewSize
设置年轻代大小(for 1.3/1.4)
-XX:MaxNewSize
年轻代最大值(for 1.3/1.4)
-XX:PermSize
设置持久代(perm gen)初始值
物理内存的1/64
-XX:MaxPermSize
设置持久代最大值
推荐阅读
- 二维码的升级版「三维码」你使用过吗?
- 保证健康的宝贵食物你掌握几种
- 开车那么久,你知道该如何保养爱车吗?
- 平板支撑有多厉害?坚持做一个月你就知道了
- 如果你正准备换发型,别错过这30款
- 蚊子最爱叮什么血型的人,你知道吗?
- 揠苗助长的意思和寓意 拔苗助长告诉我们什么道理
- 见男友的小tips是什么梗 见男友的小tips
- 中考成绩怎么查?
- 小叶紫檀|木质界的帝王之木,你了解多少?