1. Java堆内存结构
Java将堆内存分为3大部分:新生代、老年代和永久代,其中新生代又进一步划分为Eden、S0、S1(Survivor)三个区。结构如下图所示:
程序中new出来的对象会在新生代里的Eden区里面分配空间,如果存活时间足够长将会进入Survivor区,进而如果存活时间再长,还会被提升分配到老年代里面。持久代里面存放的是Class类元数据、方法描述等。
1.S0和S1是两个大小相等的区域,分配内存空间只会在其中某一个进行,另外一个空间是用来辅助进行新生代进行垃圾回收的,因为新生代的垃圾回收策略基于复制算法,其思想是将Eden区及两个Survivor中的某个区,如S0区里面需要存活的对象复制到另外一个空的Survivor区,如S1区,然后就可以回收Eden和S0区域里面的死亡对象。下一次回收就对调S0和S1两个区的角色,S1用来存放存活对象而S0用来辅助回收垃圾,如此循环利用。
2.有些文章并不将永久代纳入Java堆内存。其实永久代就是我们所说的方法区,而方法区经常被称为Non-Heap(非堆)。仅仅在HotSpot虚拟机的实现中才将GC分代收集扩展至方法区,或者说使用永久代来实现方法区,对于其他的虚拟机是不存在永久代这个概念的。
3.并非所有的对象创建都会在Eden区中分配内存空间。对于Serial和ParNew垃圾收集器,通过指定-XX:PretenureSizeThreshold={size}来设置超过这个阈值大小的对象直接进入老年代。
2. 分代回收算法
垃圾回收主要针对Java堆内存中的新生代和老年代,也正因为新生代和老年代结构上的不同,所以产生了分代回收算法,即新生代的垃圾回收和老年代的垃圾回收采用的是不同的回收算法。针对新生代,主要采用复制算法,而针对老年代,通常采用标记-清除算法或者标记-整理算法来进行回收。
2.1 复制算法
复制算法的思想是将内存分成大小相等的两块区域,每次使用其中的一块。当这一块的内存用完了,就将还存活的对象复制到另一块区域上,然后对该块进行内存回收。
这个算法实现简单,并且也相对高效,但是代价就是需要将牺牲一半的内存空间用于进行复制。有研究表明,新生代中的对象98%存活期很短,所以并不需要以1:1的比例来划分整个新生代,通常的做法是将新生代内存空间划分成一块较大的Eden区和两块较小的Survivor区,两块Survivor区域的大小保持一致。每次使用Eden和其中一块Survivor区,当回收的时候,将还存活的对象复制到另外一块Survivor空间上,最后清除Eden区和一开始使用的Survivor区。假如用于复制的Survivor区放不下存活的对象,那么会将对象存到老年代。
HotSpot虚拟机默认Eden和Survivor的大小比例是8:1:1,也就是说新生代中牺牲掉10%的空间而不是一半的空间。
2.2 标记-清除算法
标记-清除(Mark-Sweep)算法分为两个阶段:
标记
清除
在标记阶段将标记出需要回收的对象空间,然后在下一个阶段清除阶段里面,将这些标记出来的对象空间回收掉。这种算法有两个主要问题:一个是标记和清除的效率不高,另一个问题是在清理之后会产生大量不连续的内存碎片,这样会导致在分配大对象时候无法找到足够的连续内存而触发另一次垃圾收集动作。
2.3 标记-整理算法
标记-整理(Mark-Compact)算法有效预防了标记-清除算法中可能产生过多内存碎片的问题。在标记需要回收的对象以后,它会将所有存活的对象空间挪到一起,然后再执行清理。
标记-整理通常会在标记-清除算法里面作为备选方案,为了防止标记-清除后产生大量内存碎片而无法为大对象分配足够内存的情况
3. 垃圾收集器
因为新生代和老年代采用回收算法的不同,垃圾收集器相应地也分为新生代收集器和老年代收集器。其中新生代收集器主要有Serial收集器、ParNew收集器和Parallel Scavenge收集器。老年代收集器主要有Serial Old收集器、Parallel Old收集器和CMS收集器。当然还包括了一款全新的、新生代老年代通用的G1收集器。
上图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。
3.1 新生代收集器
3.1.1 Serial收集器
Serial收集器作用于新生代,是一个单线程收集器,基于复制算法实现。在进行垃圾回收的时候仅使用单条线程并且在回收的过程中会挂起所有的用户线程(Stop The World)。Serial收集器是JVM client模式下默认的新生代收集器。
特别注意,Stop-The-World会挂起应用线程,造成应用的停顿。
3.1.2 ParNew收集器
ParNew收集器作用于新生代,是一个多线程收集器,基于复制算法实现。相对于Serial收集器而言,在垃圾回收的时候会同时使用多条线程进行回收,但是它跟Serial收集器一样,在回收过程中也是会挂起所有的用户线程,从而造成应用的停顿。
3.1.3 Parallel Scavenge收集器
Parallel Scavenge收集器同样作用于新生代,并且也是采用多线程和复制算法来进行垃圾回收。Parallel Scavenge收集器关注的是吞吐量,即使得应用能够充分使用CPU。它与ParNew收集器一样,在回收过程会挂起所有的用户线程,造成应用停顿。
3.2 老年代收集器
3.2.1 Serial Old收集器
Serial Old收集器作用于老年代,采用单线程和标记-整理算法来实现垃圾回收。在回收垃圾的时候同样会挂起所有用户线程,造成应用的停顿。一般来说,老年代的容量都比新生代要大,所以当发生老年代的垃圾回收时,STW经历的时间会比新生代所用的时间长得多。该收集器是JVM client模式下默认的老年代收集器。
3.2.2 Parallel Old收集器
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,采用多线程和标记-整理算法来实现老年代的垃圾回收。这个收集器主要是为了配合Parallel Scavenge收集器的使用,即当新生代选择了Parallel Scavenge收集器的情况下,老年代可以选择Parallel Old收集器。
3.2.3 CMS收集器
CMS(Concurrent Mark Sweep)收集器是一款真正实现了并发收集的老年代收集器。CMS收集器以获取最短回收停顿时间为目标,采用多线程并发以及标记-清除算法来实现垃圾回收。CMS只在初始化标记和重新标记阶段需要挂起用户线程,造成一定的应用停顿(STW),而其他阶段收集线程都可以与用户线程并发交替进行,不必挂起用户线程,所以并不会造成应用的停顿。CMS收集器可以最大程度地减少因垃圾回收而造成应用停顿的时间。
3.2.4 G1收集器
G1收集器的优势:
(1)并行与并发
(2)分代收集
(3)空间整理 (标记整理算法,复制算法)
(4)可预测的停顿
转自:https://blog.csdn.net/d6619309/article/details/53358250
相关推荐
Java垃圾收集(Garbage Collection, 简称GC)是Java编程中的一项重要特性,它自动管理内存,释放不再使用的对象,避免了程序员手动管理内存可能导致的内存泄露问题。本篇将深入探讨Java中的GC过程。 一、Java内存...
Java GC与性能调优 Java GC与性能调优是 Java programming language 中非常重要的一部分,直接影响着 Java application 的性能。本文档将对 Java GC 与性能调优进行详细的介绍。 一、 Java 平台的逻辑结构 Java ...
在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项至关重要的机制,它自动管理内存,释放不再使用的对象,防止内存泄漏。本篇将深入探讨如何监控Java的垃圾回收,帮助开发者提升应用性能和稳定性。 Java...
### Java GC工作原理详解 #### 一、引言 在现代软件开发中,Java作为一种广泛使用的编程语言,其强大的功能和高效性深受开发者喜爱。Java的自动内存管理机制是其一大亮点,尤其体现在垃圾收集(Garbage Collection...
### Java GC垃圾回收调优指南 #### 概述 在Java开发过程中,垃圾回收(Garbage Collection, GC)是管理内存资源的关键技术之一。合理的GC配置可以显著提高应用程序的性能和稳定性。本指南旨在帮助开发者深入理解...
Java虚拟机(JVM)是运行Java字节码的虚拟机进程。它负责在不同操作系统上...以上就是对JavaGC专家指南中提到的知识点的一个全面解析,涵盖了从虚拟机的基本概念到内存管理,再到垃圾回收和性能调优的各个重要方面。
【Java GC机制详解】 Java垃圾回收(Garbage Collection, GC)是Java虚拟机(JVM)的核心特性之一,它负责自动管理程序运行时的内存,有效地避免了内存泄露和溢出的问题。Java GC机制主要涉及以下几个关键方面: 1...
Java垃圾收集(Garbage Collection, 简称GC)是Java编程中一个重要的概念,它负责自动管理程序中的内存,回收不再使用的对象所占用的内存空间。GC调优是优化Java应用程序性能的关键环节,尤其是在大型系统中,正确...
GC java 手册 kindle格式 GC java 手册 kindle格式 GC java 手册 kindle格式
Java垃圾收集(GC)是Java编程中至关重要的一个部分,它自动管理程序的内存,以避免内存泄漏和系统资源耗尽。以下是对标题和描述中提及的知识点的详细阐述: ### 1. 基础知识 #### 1.1 常见的内存溢出 内存溢出是...
JAVA GC (Garbage Collection) 是Java编程语言中的一个重要特性,它自动管理程序的内存,确保不再使用的对象能够被及时回收,以防止内存泄漏。GC主要针对的是Java堆内存中的对象,这里的对象是由Java栈中的引用指向...
【Java GC on HP-UX Itanium】和【JDK on HP-UX 简要介绍及性能调试概要】这两个主题涉及到的是Java在HP-UX操作系统上的运行环境、内存管理和性能优化,特别是针对Itanium架构的Java垃圾收集(GC)机制。以下是详细...
Java垃圾收集(Garbage Collection, 简称GC)是Java编程中的一个重要概念,它自动管理内存,使得程序员不必手动释放不再使用的对象,从而避免了内存泄漏的问题。本专题将深入探讨Java GC的基础知识,包括其工作原理...
在第一篇文章成为JavaGC专家PartI—深入浅出Java垃圾回收机制中我们学习了不同GC算法的执行过程,GC如何工作,新生代及老年代的基本概念,在JDK7中你应该了解的5种GC类型以及他们的性能如何。在第二篇文章成为JavaGC...
Java虚拟机(JVM)是Java程序运行的基础,它的配置参数和垃圾收集(GC)机制对于优化应用程序性能至关重要。本文将深入探讨JVM参数及其与Java垃圾收集相关的知识。 一、JVM参数详解 JVM参数可以分为三类:启动参数...
Java垃圾收集(Garbage Collection, 简称GC)是Java平台中的一项重要特性,它自动管理程序的内存,使得开发者无需手动进行内存分配和释放。然而,GC调优是每个Java开发者都需要面对的挑战,因为合适的GC配置可以显著...
对于Java开发人员来说,了解垃圾回收机制(GC)有哪些好处呢?首先可以满足作为一名软件工程师的求知欲,其次,深入了解GC如何工作可以...这是成为JavaGC专家系列文章的第一篇,本篇主要针对GC机制进行介绍,在下一篇