IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

标签:GC

共 11 篇相关文章

IT 累计浏览 2,465

Java -- Hotspot虚拟机调优与GC垃圾回收策略

这篇讲的是Java HotSpot虚拟机如何进行性能调优,核心是理解并优化其垃圾回收(GC)机制。作者从Java与C/C++的常见争论切入,指出Java在动态优化方面的特性,引出对JVM和GC进行研究的必要性。 文章首先详细图解了JVM的堆内存分区:Eden、Survivor、老年代和持久代,解释了各区域的用途。接着,重点剖析了GC的核心流程与算法,从经典的引用计数法和Java实际采用的根搜索法说起,对比分析了标记-清除、复制(用于新生代)、标记-整理(用于老年代)等回收算法的原理与优缺点,特别阐述了它们如何协同工作以平衡效率与内存碎片问题。 最后,文章落脚于实践,列举了如-XX:-DisableExplicitGC、-XX:+UseConcMarkSweepGC等一系列关键的JVM启动参数,并结合Full GC与Young GC的特点,提供了具体的调优方向与性能优化Tips,帮助开发者从理论到实践全面掌握GC调优。

IT 累计浏览 3,841

JVM的GC简介和实例

这篇文章从JVM内存布局讲起,重点剖析了Java堆的分代模型——新生代如何划分Eden与Survivor区,以及Minor GC触发时基于复制算法的运作机制。作者通过一段简单代码和jstat监控,演示了在默认配置下,新对象如何优先在Eden区分配,当Eden空间不足时如何触发一次Minor GC,以及部分存活对象如何被直接晋升到老年代。整个过程配合真实的GC日志进行了拆解。 文章还简要介绍了Serial、ParNew、CMS等常见的垃圾收集器,并利用JVM参数(如-Xmn、-XX:SurvivorRatio)调整新生代配置,为后续对比不同收集器的行为埋下伏笔。它并非泛泛而谈理论,而是将“对象优先在Eden分配”、“大对象直接进入老年代”等原则,用可观察的内存变化和日志数据做了印证。对于想理解GC基本行为,或对“Minor GC后对象为何直接进入老年代”感到困惑的初学者,这份实战记录提供了清晰的图示和数据支撑。

IT 累计浏览 3,828

JVM垃圾收集器

这篇讲的是JVM中垃圾收集器的原理与选型。作者从垃圾收集是算法的具体实现出发,系统梳理了JDK 1.6时代的六种主流收集器。 文章的核心在于对比。它首先指出没有万能收集器,只有最合适的。Serial作为单线程基础款,适合客户端;ParNew是其多线程升级版,主要为了配合CMS;Parallel Scavenge则专注于吞吐量,适合后台计算任务。在老年代,Serial Old是单线程整理,Parallel Old实现了多线程整理以贯彻高吞吐思路。 重点落在两种并发收集器上。CMS以最短停顿为目标,通过并发标记清除实现,但面临CPU敏感、浮动垃圾和空间碎片问题。G1则带来了革命性改进:基于标记-整理,不产生碎片;通过将堆划分为多个Region并优先回收垃圾最多的区域,实现了可预测的、精确的停顿时间控制。 文章结合图示,清晰地展示了各收集器的适用年代、组合方式以及从Serial到G1,用户线程停顿时间不断缩短的发展脉络,为理解JVM内存管理提供了扎实的入门图景。

IT 累计浏览 2,861

把 lua 的 gc 移到独立线程

这篇讲的是如何将 Lua 的垃圾回收(GC)机制从主线程剥离,放到独立线程中运行的技术方案。 作者首先剖析了 Lua 现有 GC 工作机制的细节,指出了其核心痛点:GC 的标记、清除等阶段会与业务代码共享同一个执行线程,不可避免地导致不可预测的长时间停顿,这对于延迟敏感的应用(如游戏、实时服务)是个棘手问题。 文章的核心思路是实现一个“GC 线程”,让它与主线程并行工作。难点在于如何让 GC 线程安全地遍历和清理仍被主线程使用的对象。作者从 Lua 源码出发,阐述了实现的关键点,包括设计一套轻量级的屏障(barrier)机制来记录对象修改、协调两个线程间的对象图访问,以及处理字符串等特殊对象的清理逻辑。 经过改造后,GC 工作主要转至后台,主线程仅需付出很小的屏障开销,从而大幅降低了 GC 引起的峰值停顿。文章不仅给出了清晰的实现路径,也坦诚讨论了并行 GC 带来的额外内存占用等权衡,为需要进行类似优化的开发者提供了扎实的参考。

IT 累计浏览 3,866

Lua GC 的源码剖析 (6) 完结

这篇讲的是 Lua 虚拟机垃圾回收(GC)系列分析的最后篇章。作者在之前几篇中已经深入拆解了 GC 中最复杂的标记(mark)阶段,而这篇则专注于清理剩余的部分。他从整体 GC 流程的收尾工作入手,阐述了标记完成后,清除(sweep)阶段和增量(incremental)阶段的具体实现。 核心实现思路清晰而巧妙:文章解释了如何通过写屏障(write barrier)技术来支持增量式回收,避免长时间的停顿;同时,也剖析了清扫阶段如何高效地回收内存并维护空闲链表。作者特别强调了 Lua GC 的“分代”与“增量”特性是如何在底层代码中协同工作的,展示了开发者为平衡性能与实时性所做的精细设计。 整体来看,作者用连贯的源码走读,将复杂的 GC 流程收束。他不仅解释了“是什么”,更通过代码级的细节,让读者理解 Lua 选择这种实现的“为什么”。对于想完整理解 Lua 内存管理机制的开发者而言,这为系列画上了一个清晰的句号。

IT 累计浏览 2,762

Lua GC 的源码剖析 (5)

这篇讲的是Lua垃圾回收器中一个关键机制的实现细节:write barrier(写屏障)。在增量式GC中,为了保持对象图的一致性,当程序修改一个可能被GC扫描的对象的引用时,需要额外进行标记处理——这就是write barrier要解决的问题。 文章没有停留在概念层面,而是直接切入源码。作者从`luaC_barrier`等函数入手,剖析了Lua GC中三种不同类型的写屏障(普通写屏障、快速写屏障和表写屏障)的具体实现逻辑。比如,对于表的操作,屏障会判断被修改的值是否为白色(未标记),并将相关对象加入一个“gray”列表,确保后续的增量扫描不会遗漏。 最巧妙的部分在于这种“即时记录”的思路:与其在GC周期结束后费力重扫整个对象图,不如在每次可能产生不一致的写操作时,就即时、低成本地记录下变化。文章通过源码展示了这种权衡是如何在性能和正确性之间取得平衡的,对于想理解动态语言GC底层工程实践的人来说,提供了非常扎实的参考。

IT 累计浏览 4,724

Lua GC 的源码剖析 (4)

这篇讲的是Lua垃圾回收(GC)中至关重要的标记(mark)过程实现。作为系列分析的第四篇,作者从GC的整体流程切入,将镜头聚焦到标记阶段:它如何从根集合出发,精准地标记出所有存活对象,同时避免程序在运行中修改对象引用而导致标记错误。 文章的核心在于剖析Lua采用的“三色标记法”与写屏障(write barrier)机制的协同工作。作者通过源码走读,展示了灰色、黑色、白色对象状态之间的转换逻辑,以及当黑色对象被赋予白色引用时,写屏障如何“拦截”并记录这一变化,确保后续能正确标记。实现上,Lua为不同状态的对象维护了不同的链表,这种设计让遍历和状态转移都十分高效。 更巧妙的是,Lua针对不同对象类型(如表、字符串、闭包)采用了差异化的标记策略。例如,对于表的标记会递归处理其键值对,而字符串则利用其不可变性简化了流程。这种细致的实现兼顾了正确性与性能。作者在剖析中也点出了这种设计背后对运行时效率和代码复杂度的权衡思考,让人看到一个高效GC背后的精巧工程实现。

IT 累计浏览 3,502

Lua GC 的源码剖析 (3)

这篇讲的是Lua垃圾回收(GC)机制的深入实现剖析,作为系列第三篇,它在已有知识基础上,开始带领读者从整体架构自顶向下阅读GC模块的核心源码。 作者没有停留在概念层面,而是直接切入代码,展示了GC如何通过“增量回收”策略来控制每次回收的停顿时间。文章重点分析了“三色标记法”的具体实现,详细解释了白色、灰色、黑色对象状态如何在代码中流转,以及屏障机制如何保证并发标记的一致性。特别值得注意的是,文中对“弱表”在GC过程中的特殊处理进行了细致的代码级解读,揭示了这一常用特性的底层奥秘。 通过这种逐行深入的方式,文章将复杂的回收算法具象化为清晰的代码逻辑,对于想要理解GC如何在实际中权衡性能与效率、或是有志于优化脚本引擎的开发者来说,能提供非常扎实的底层认知。

IT 累计浏览 4,303

Lua GC 的源码剖析 (1)

这篇讲的是 Lua 虚拟机中最核心的自动内存管理模块——垃圾回收器(GC)是如何从源码层面实现的。作者从 GC 的核心目标(自动回收无用内存)出发,直接深入到源码实现,详细拆解了其工作原理。 文章重点剖析了 Lua GC 采用的“三色标记”算法,并解释了其中“写屏障”这一巧妙机制如何保证在并发标记阶段不会遗漏存活对象。作者还梳理了 Lua GC 如何通过增量回收和分代回收等策略,在保证回收效率的同时,努力降低对程序运行造成的卡顿影响。 整篇分析不是泛泛而谈,而是紧扣源码中的数据结构和函数调用,把“标记-清除”、“增量更新”这些抽象概念与具体的代码逻辑对应起来,清晰地展现了 Lua GC 在简洁性与高效性之间进行权衡的设计思路。

IT 累计浏览 3,220

在 C++ 中引入 gc 后的对象初始化

这篇讲的是在 C++ 世界里引入垃圾回收机制后,一个容易被忽视但至关重要的挑战:对象初始化。 我们知道,C++ 对象的创建分为两步:内存分配与构造函数调用。构造函数是对象安全可用的保证。然而,传统的垃圾回收器并不理解这种语义。它可能会在对象刚被分配、但构造函数还未执行完(甚至刚开始)时,就错误地回收这块内存。这会导致出现“半初始化”的对象,程序访问其成员变量时便会引发难以排查的错误。 文章作者从这个痛点出发,深入探讨了不同 GC 实现与 C++ 对象模型交互时可能产生的具体风险。核心方案上,作者倾向于一种“延迟回收”或“构造函数保护”策略:在对象构造完成之前,禁止垃圾回收器将其标记为可回收。这确保了从构造函数开始到结束,对象所使用的内存都是安全且私有的。 这种设计需要在 GC 的安全性与 C++ 原生对象生命周期管理的完整性之间做出精巧的平衡。作者的分析表明,通过明确区分“分配”与“初始化”阶段并施加相应约束,可以在享受自动内存管理便利的同时,不破坏 C++ 对程序员确定性的承诺,为系统级编程中融合 GC 提供了可靠的思路。

IT 累计浏览 3,601

Ruby作为服务器端应用已经成熟了

这篇讲的是JavaEye团队在将Ruby on Rails应用于生产环境后,遭遇的一个棘手难题:Ruby进程的内存泄露。 他们的服务器因此深受其扰,不得不自己动手开发了一套监控脚本,来实时检测和定位泄露的Ruby进程。文章深入探讨了导致Ruby内存管理不善的两个核心原因。虽然标题提到了Ruby的“成熟”,但作者并非唱赞歌,而是从这些实际踩过的“坑”出发,坦诚地剖析了作为服务器端语言在内存控制层面存在的挑战与实践经验。 对于正在使用或考虑采用Ruby的技术团队而言,这篇文章的价值在于它并非泛泛而谈的优劣对比,而是提供了来自生产一线的第一手排查思路与教训,其中关于监控脚本的实践部分尤其具有参考意义。