关于JVM内存管理或垃圾收集,您可能已经阅读了很多文章,我将为每个人总结一下。我在本文中也多次研究,我也间歇性地研究。在未来的文章中,会有也是知识点之类的东西。我没有关于我的文章的计划。在了解了什么知识之后,我将在理解之后写一些知识。为了记录您自己的学习并理解您的思想并进行简单分享。
什么是GC根:
以上不是完整的,但这足够了。
可用分析:通过一系列“ GC根”对象作为起点搜索。如果“ GC根”和一个对象之间没有路径,则该对象被认为是无法实现的。应该注意的是非目标对象不等于可回收的对象,不可访问的对象至少成为至少两次可回收对象。两个标记仍然可回收后,它们将面临回收利用。
参考计数方法将不会详细引入。参考计数不符?
思考为什么需要对学位分析进行两次标记?
如果发现对象是执行表演者后未连接到GC根的参考链,则将首次标记和筛选它。或JVM调用了finalize()方法,虚拟机认为这两种情况是“无需执行”。目前,对象是真实的“ dead'Object”。
如果该对象被判断为执行finalize()方法,则将该对象放置在称为f-quesue的队列中,并且它将由虚拟机自动建立,以使用低优先级终结器线程执行它以执行它(该执行它)IS,虚拟机的finalize()方法触发finalize()方法),finalize()方法是逃脱对象死亡的最后机会。一次被救出);如果对象未能成功保存在finalize()中,则将立即恢复。
任何对象的finalize()方法只能由系统调用一次。如果相同的对象在逃脱后再次面对,则不会再次执行其Fianlize()方法。
为什么最终()方法仅由系统调用一次并判断条件?交叉点是什么优点?交叉点
示例代码:
垃圾回收:
Minjorgc:在充满了光明世代之后,将进行年轻一代的垃圾收集
全GC/Major GC:全GC将收集所有区域,收集年轻人,使用年轻一代垃圾回收算法,然后使用旧一代的垃圾回收算法来回收旧一代和永久世代。被独立压缩。
根据统计,计算了年轻一代的平均规模。如果(老年的剩余空间 < 平均大小) 触发 full gc。
快速分配:
对于多线程应用,对象分配必须要保证线程安全性,如果使用全局锁,那么分配空间将成为瓶颈并降低程序性能。HotSpot 使用了称之为 Thread-Local Allocation Buffers (TLABs) 的技术,该技术能改善多线程空间分配的吞吐量。首先,给予每个线程一部分内存作为缓存区,每个线程都在自己的缓存区中进行指针碰撞,这样就不用获取全局锁了。只有当一个线程使用完了它的 TLAB,它才需要使用同步来获取一个新的缓冲区。HotSpot 使用了多项技术来降低 TLAB 对于内存的浪费。比如,TLAB 的平均大小被限制在 Eden 区大小的 1% 之内。TLABs 和使用指针碰撞的线性分配结合,使得内存分配非常简单高效,只需要大概 10 条机器指令就可以完成。
CMS 收集过程首先是一段小停顿 stop-the-world,叫做 初始标记阶段(initial mark),用于确定 GC Roots。然后是 并发标记阶段(concurrent mark),标记 GC Roots 可达的所有存活对象,由于这个阶段应用程序同时也在运行,所以并发标记阶段结束后,并不能标记出所有的存活对象。为了解决这个问题,需要再次停顿应用程序,称为 再次标记阶段(remark),遍历在并发标记阶段应用程序修改的对象(标记出应用程序在这个期间的活对象),由于这次停顿比初始标记要长得多,所以会使用多线程并行执行来增加效率。
再次标记阶段结束后,能保证所有存活对象都被标记完成,所以接下来的 并发清理阶段(concurrent sweep) 将就地回收垃圾对象所占空间。下图示意了老年代中 串行、标记 -> 清洁 - >压缩收集器和CMS收集器之间的区别:
由于某些任务增加了收集器的工作,例如应用程序阶段的应用对象,因此添加了CMS收集器负载。对于大多数试图减少停顿的收集者,这是一个称重解决方案。
CMS收集器是唯一不压缩的收集器。在释放垃圾物体所占据的空间后,它不会将幸存的物体移至侧面。
这将节省垃圾回收的时间,但是由于将来的自由空间不连续,因此无法通过简单的指针碰撞来分配对象空间。它需要保持休闲列表并连接所有自由区域。分配空间时,您需要找到一个可以容纳对象的区域。显然,它的成本比使用简单的指针碰撞成本高。同时,它也会增加年轻一代垃圾收集的负载,因为如果目标是年轻一代已晋升为老年,需要在老年分发。
另一个缺点是,CMS收集器需要使用比其他收集器更大的堆叠内存。由于该程序需要在并发标记阶段执行,因此有足够的空间可供应用程序。在商标阶段确定,因为应用程序同时运行,刚刚标记的生存对象很可能立即成为垃圾,并且该部分仅被标记为生存对象,因此只能在直到直到下一个老年,垃圾的这一部分称为浮动垃圾。
最后,由于缺乏压缩链接,该堆将存在分散的问题。为了解决此问题,CMS Collector需要跟踪统计数据中最常用的对象大小。评估未来的分配需求也可能需要划分或合并闲置区域。
与其他垃圾收集器不同,直到老年才能收集CMS收集器。收集器需要计算每个垃圾收集的时间和老年的速度。此外,如果在初始职业率(初始居住)中消耗该空间,它也会一次触发垃圾收集。该占用率是通过-XX设置的:CMSInitiaingOcatingCupanceFraction = N.IT 68。
CMS收集器可以使用增量模式。在并发标记阶段,将CPU时钟周期列入应用程序。此功能适用于CMS的低潜伏期,但CPU核心仅为一两个。
何时使用CMS收集器
它适用于应用程序停止的应用,同时,它可以接受共享CPU资源的场景以及垃圾收集阶段期间的垃圾收集线程。典型是Web应用程序。
G1的主要关注是达到控制时间,并在此基础上尽可能地增加吞吐量,这非常重要。
G1没有CMS(或不那么严重)的破碎问题,并且同时提供了更可控制的停顿。
如果您的应用程序使用大量堆(例如6GB及以上),并且需要较低的垃圾收集才能停止暂停(例如0.5秒),那么G1是您的最佳选择,现在是时候放弃CMS了。
G1将整个堆划分为相同大小的小部分(每个部分称为区域),并且每件的记忆是连续的。和旧的,但它们不是固定的,这使得内存的使用更加灵活。
G1集合线程在标记阶段和应用程序线程中同时执行。标记结束后,G1还知道哪些块基本上是垃圾,而且幸存的物体很少。G1将从这些块开始,因为这些块可以很好地从这些块中开始,因为这些块可以很好地从这些块中出现,因为这些块可以从这些块中非常好,因为这些块可以从这些块中非常好,因为从这些块中可以很好地从这些块中来看这些块,因为这些块可以非常好,因为这些块可以从这些块中非常好,因为这些块可以从这些块中非常好,因为这些块可以是这些块非常好,因为这些块可以很好地从这些块中出现。
使用-xx:maxGcpausemilis = 200来指定预期的暂停时间。
G1使用暂停预测模型来满足用户指定的停止目标,并根据目标选择垃圾回收的块数量。G1使用增量回收方法每次恢复一些块,而不是整个回收堆。
G1需要比并联和CMS更多的内存消耗,因为在簿记的帐户上消耗了某些内存消耗,如以下两个数据结构:
G1收集器主要包括以下4个操作:
那么,并发标记周期何时开始?这是由参数控制的。立即引入以下参数。该参数的默认值为45,这意味着当使用桩空间45%时,G1将进入并发标记周期。
G1调整的目标是避免尽可能多地出现在全GC中。实际上,足以为老年人或相对较大的空间腾出足够的空间。
我们可以进行以下几点调整:
G1的重要目标是实现可控的停顿,因此以此目标执行了许多行为。
我们通过设置-XX:MAXGCPAUSEMILLIS = n来指定暂停时间(单位MS,默认200ms)。如果未实现此目标,将以各种方式对G1进行修复:调整年轻和老年的比例,调整堆的大小,调整大小的调整,调整调整的促销年龄阈值,调整在混合垃圾回收周期中处理的老一代,依此类推。
分配给类的空间是属于此类的类加载程序。只有在卸载此类加载程序时,该空间才会发布。
因此,只有当该类加载器加载的所有类未幸存下来,并且没有达到这些类和类加载器的参考时,相应的METASPACE空间将由GC发布。
因此,Metaspace中Java类占据的空间取决于该类的类加载程序是否已卸载。
METASPACE空间的释放并不意味着该空间的这一部分已返回到系统内存,并且空间的这一部分通常由JVM保留。
保留该部分的大小取决于Metaspace的破碎程度。此外,Metaspace中的某些区域是压缩的类空间,并且不会为操作系统偿还它们。
在64位平台上,热点使用两种压缩优化技术,压缩对象指针(
“压缩锅”
)和压缩类指针。
压缩指针是指在64位计算机上访问数据(Metaspace中的对象或元数据)的一种方法。
这有许多好处,例如32位指针占据较小的内存,可以更好地使用缓存。在某些平台上,可以使用更多寄存器。
当然,在64位计算机中,最终需要一个64位地址来访问数据,因此该32 -bit的值是参考地址的值。
Metaspace可能在两种情况下触发GC:
1.分配空间时:虚拟机保持阈值。如果Metaspace空间的大小超过此阈值,那么当应用新的空间分配应用程序时,虚拟机将首先实现未安装的类加载程序以实现重复使用空间。可振动,而不是扩展Metaspace的空间。目前,将触发GC。该阈值将在上下调整,并与Metaspace所占据的操作系统内存保持距离。
2.封闭式METASPACE OOM:MEDASPACE的总空间已达到MaxMetaspaceize设置的阈值,或者使用了轻度的级别。
当Virtual -SpacelistNode中的所有块都是空闲的时,该节点将从链接的列表virtual -Spacelist中删除,并且其块将从idle List.serating System中删除。