Ⅰ java中的垃圾回收是什么意思
Java中的垃圾回收是指Java虚拟机提供的一种能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。具体来说:
回收对象:垃圾回收的目标是回收无任何引用的对象占据的内存空间,而不是对象本身。这些对象被认为是“垃圾”,因为它们已经不被程序中的任何部分所使用。
运行时间:垃圾回收器的运行时间是不确定的,由JVM决定。它在运行时是间歇执行的,这意味着它会在JVM认为合适的时候进行垃圾回收,而不是按照固定的时间间隔。
强制回收:虽然可以通过系统命令来强制JVM进行垃圾回收,但是这个命令下达后并不能保证JVM会立即响应执行。然而,经验表明,在下达命令后,JVM通常会在短期内执行垃圾回收操作。
内存管理:系统通常会在感到内存紧缺时去执行垃圾回收操作,以释放不再使用的内存空间。垃圾回收的频率对程序性能有影响:过于频繁会导致性能下降,因为垃圾回收过程会占用CPU资源;而过于稀疏则可能导致内存紧缺,影响程序的正常运行。
因此,Java中的垃圾回收是一种重要的内存管理机制,它有助于自动管理内存,减少内存泄漏的风险,但也需要开发者注意其可能带来的性能影响。
Ⅱ java垃圾回收器有哪几种
Java垃圾回收算法和收集器是系统自动管理内存的关键部分。主要有以下几种:
1. 标记-清除算法:简单实现,不产生内存碎片,但清除操作可能引起停顿且导致大量不连续内存碎片。
2. 复制算法:实现简单,无内存碎片,适用于新生代,但需要额外内存空间。
3. 标记-压缩算法:解决内存碎片问题,移动存活对象,减少停顿时间,但操作复杂。
4. 分代收集算法:依据对象生命周期,将堆划分为新生代和老年代,针对性管理,提高效率,增加系统复杂度。
5. 增量收集与并发收集:为其他算法优化,提升收集效率。
Java中常见的收集器包括:
1. Serial Collector:单线程收集,适用于单CPU或小内存场景。
2. Parallel Collector:多线程执行,适用于多CPU且不敏感于停顿时间的应用。
3. ParNew Collector:专为多线程环境设计,配合CMS收集器使用,提升多代垃圾收集效率。
4. CMS Collector:以最短停顿时间为目标,实现并发标记、清理,大部分工作与用户线程并发进行。
5. G1 Collector:分代收集器,将堆划分为多个区域,预测停顿时间,采用标记-压缩算法,兼顾吞吐量和停顿时间。
6. ZGC与Shenandoah:低延迟垃圾收集器,实现亚毫秒级停顿,采用颜色指针、读屏障、并发压缩等技术。
这些算法和收集器各有特点,开发者应根据应用需求选择合适的垃圾回收配置,以实现最佳性能。
Ⅲ JAVA垃圾回收器-上篇
学习背景
在学习垃圾回收器之前,我们首先明确目标。大多数人学习垃圾回收器主要是为了应对面试,因为这一知识点十分重要,系统全面的介绍却不多见。本篇主要讲述垃圾回收器的实现思想与部分原理,为方便阅读,我们还会介绍一些术语。
垃圾回收器是什么
垃圾回收器作为JVM的一部分,负责管理内存,包括对象的分配与回收,以确保程序运行安全且高效。虽然从职责上来说,它可以视为一个抽象实体,但实际上,不同JVM实现中可能存在多种垃圾回收器,甚至一个JVM内部就可能包含多个回收器。它们依据对象特点选择算法与内存管理方式,有效利用内存资源。
在开始深入学习之前,让我们了解一下JVM的几个主要实现及其历史,这些实现正是垃圾回收器的理论基础。
在后续的理论讲解中,我们将重点使用HotSpot虚拟机作为示例进行讨论。
JVM内存区域
在探索垃圾回收器之前,理解JVM内存布局至关重要,这有助于我们更好地理解回收机制及其工作原理。《Java虚拟机规范》定义了JVM内存布局,主要包括几个关键区域。
接下来的解释可能会让你感到困惑,但请放心,我们即将步入正题。在深入垃圾回收器理论之前,我们也将简要介绍对象创建与内存布局的内容,但为了保持文章流畅,这部分将在后续编译器内容中详细介绍。
垃圾回收理论指导思想
在了解垃圾回收器的工作机制之前,先思考如何回收一个对象。大致而言,这分为识别垃圾与引用计数与可达性分析算法两个步骤。
识别垃圾
假设我们有一个记录对象引用次数的区域,每当其他对象引用某个对象时,次数加一,引用失效时减一。当引用次数归零,说明对象已无用,可以被回收。这是简单朴素的思路,许多软件采用此法,如FlashPlayer、Python、Redis等,但在Java中,主流JVM未采用此算法,因为它难以处理循环引用问题。
可达性分析算法
主流现代JVM采用可达性分析算法,从称为GC根的对象出发,遍历其引用的对象,找到引用链上的存活对象,以此判断对象是否可以被回收。
何为引用
在上述介绍中,我们遇到了一个关键概念——引用。引用定义了对象之间的关系,其正式定义在JDK 1.2后出现。引用大致分为四类,但在本文中,我们主要关注其基本用法。
回收垃圾分代收集算法
在介绍内存回收方式之前,我们先了解分代收集算法。通过将对象按年龄分代,年轻对象存于新生代,年长对象存于老年代。这影响了垃圾回收算法的实现。
标记清除算法
标记清除算法通过标记与清除阶段回收内存。标记阶段与可达性分析一致,清除阶段统一回收标记的对象。但这种方法可能导致内存碎片,影响后续分配。
复制算法
复制算法改进了标记清除算法,将内存划分为两部分,每次使用其中一部分。回收后,存活对象复制到另一部分,清理原区域。此方法避免了内存不连续问题,但牺牲了运行内存空间。
现代商业虚拟机采用这种算法,如HotSpot中,新生代划分为Eden区与两块Survivor区。回收时,将存活对象复制到Survivor区,清理Eden与原Survivor区。默认比例为8:1:1,每次新生代可用内存为整个新生代的90%。
标记整理算法
复制算法存在不足,因此老年代通常采用标记整理算法。此算法首先标记存活对象,将它们移动至内存一端,然后回收边界外内存。
HotSpot的垃圾回收设计
HotSpot虚拟机的垃圾收集设计基于前述理论,下面我们将介绍实际设计点,这些点需要结合具体垃圾回收器进行深入理解。
根节点枚举
可达性分析算法中,找到GC根对象至关重要。HotSpot使用OopMap加速此过程,记录对象与栈、寄存器中的引用位置,避免扫描方法区。
安全点与安全区
生成Oop Map的位置限于安全点与安全区。安全点确保程序长时间执行,安全区允许引用关系在一定代码内保持不变。
垃圾回收器介绍
理论铺垫后,我们将开始实际垃圾回收器的学习。
Serial搜集器
这是JDK最古老的收集器,单线程运行,暂停所有工作线程。在Client模式下,它作为新生代默认收集器。
Serial Old收集器
它是Serial收集器的老年代版本,同样为单线程收集器,采用标记整理算法。在Client模式下使用,配合Parallel Scavenge使用时作为CMS失败时的后备方案。
ParNew收集器
Serial收集器的多线程版本,Server模式下新生代首选。单核环境下性能与Serial相当。
Parallel Scavenge收集器
多线程新生代收集器,追求可控吞吐量,更关注运行时间与垃圾收集时间的比值。有重要参数可调整吞吐量与停顿时间。
Parallel Old收集器
Parallel Old是ParNew的老年代版本,使用多线程与标记整理算法。配合Parallel Scavenge使用,适合吞吐量优先场景。
CMS(Concurrent Mark Sweep)收集器
CMS是老年代收集器,基于标记清除算法,目标是降低停顿时间。开启方法为-XX:+UseConcMarkSweepGC,回收过程包含初始标记、并发标记、重新标记与并发清除等步骤。
CMS收集器优点与缺点
CMS收集器减少STW时间,适合网络服务器,但也存在停顿时间长、内存碎片、并发控制复杂等缺点。
总结与展望
本文主要回顾了垃圾回收器的基础理论与常见实现。了解了这些理论后,下一步是深入学习具体垃圾回收器的回收细节。在后续文章中,我们将详细介绍G1与ZGC等收集器,以及GC日志的知识。敬请期待。