`

垃圾回收基础知识

 
阅读更多

一、简介

在C/C++中,都可以直接操作指针,分配内存都需要显式释放。

C++有构造函数和析构函数,创建对象用new,销毁对象用delete。C分配内存用malloc和free。

而java中,只需要显式的new出对象,具体什么时候销毁,就由JVM决定了,不需要人工干预。但是我么还是最好明白JVM垃圾回收的原理,出现问题也容易排查。

 

二、虚拟机基本结构

以Sun Hotspot Jvm 1.7 为例,虚拟机结构如下图:


                    
   hotspot JVM使用了分代的结构。对象分配时,会首先进入新生代,之后一部分留在新生代,一部分晋级老年代。

   Jdk1.8,取消了永久代。

    

三、垃圾回收算法

垃圾回收,都是从根对象开始,遍历所有可以到达的对象,未到达的就是垃圾对象。回收算法共有种。如下:

1、引用计数法

引用计数法的原理,是只要有一个对象引用了A对象,则A的计数器加1。引用失效,计数器减1.

HotSpot没有采用该种办法,有两个原因:

①无法处理相互引用的情况。当两个对象都无用,但是相互引用,该算法认为对象还有用

②随着引用的添加与失效,伴随着加减的操作,浪费性能

 

2、标记清除法

首先通过根节点,遍历出所有可到达的对象并标记。之后清除所有未标记的对象。

该算法最大问题,是造成内存碎片

 

3、复制算法

将内存分成两块,每次只使用一块。垃圾回收时,将有效的对象,复制到另一块区域,然后直接清空之前那一块区域。

缺点:内存折半,真正使用的内存区域,只有一半。

单纯的复制算法无法让人接受,但是可以部分的采用。比如上图的HotSpot,新生代中的from和to区域,就是采用的复制算法,后文会说明

 

4、标记压缩法

在标记完对象后,将有效对象都压缩到内存的一侧。相当于标记清楚 + 内存整理

 

其他综合算法

分代算法

将内存分成多个代,比如上图的新生代,老年代,每次根据内存的特点,使用不同的回收算法。

新生代: 复制算法

老年代:标记清理,或标记压缩法

 

分区算法

将内存分成多个区域,每次回收一部分区域,能有效的控制GC停顿的时间

 

三、垃圾回收器

1、新生代串行回收器

缺点:

     ① 仅使用单线程回收

     ② 独占式回收。也就是说,回收时所有线程都需要暂停,也就是 stop the world.

优点:使用的是复制算法,对单CPU处理器等,性能表现超过并行和并发回收器。Client模式,是默认的回收器

 

2、老年代串行回收器

使用标记压缩算法

缺点:

①串行

②老年代比新生代一般需要更久,停顿时间也会更久,一般是和多种新生代回收器配合使用,也可以作为CMS的备用回收器

 

3、新生代ParNew回收器

简单的将串行回收器多线程化,其他一模一样

缺点:

    并发能力强的CPU上,停顿时间短于串行回收器,在单CPU或并发能力弱的系统中,因为多线程的压力,效果要差于串行回收器

 

4、新生代ParellelGC回收器

使用复制算法,也是一个多线程,独占式的回收器,关注系统吞吐量

 

5、老年代ParellelOldGC回收器

需要和ParellelGC配合才能使用,使用标记压缩法

 

6、并发标记清除CMS回收器

全称为Concurrent Mark Sweep。关注系统停顿时间。

所谓并发,是回收器和应用程序交替执行,也就是多线程编程中常说的并发。而并行,多个线程一起GC,但应用程序是停止的

CMS比较复杂点,分为初始标记,并发标记,预清理,重新标记,并发清除和并发重

缺点:内存碎片

-XX:+UseCMSCpmpactAtFullCollect,可以使CMS回收完成后,进行一次内存整理,但内存整理不是并发的

-XX:CMSFullGCsBeforeCompaction ,设定多少次CMS回收后,进行一次内存压缩

 

7、G1回收器

Jdk1.7中应用的最新的垃圾回收,期望解决CMS中内存碎片的问题,使用分区算法

特点:

    ① 并行

    ② 并发,不会 在整个回收期间完全阻塞应用程序

    ③ 分代GC:同时兼顾新生代和老年代

    ④ 空间整理:回收中会进行适当的对象移动,减少空间碎片

    ⑤ 每次只选择部分区域进行回收

 

四、hotspot的回收策略

      新生代的from,to都叫survivor区,默认Eden,和from,to的比例是8:1:1

                          

    1、new的对象,基本都是分配在Eden区的,少数情况例外,比如分配在TLAB中

    2、GC触发后,eden区的有效对象会被复制到from或to中,假设是from。大对象可能直接进入了老年代,如果from已满,也会直接进入老年代

    3、此时eden区和to区的对象,都是垃圾对象,可以直接清空。

    4、下一次GC时,from是有对象的,eden区和from区域的有效对象,会进入to区或老年代,规则和第2条相同。也就是说,from和to是使用复制算法的一个典型应用,保证其中一个为空,gc时将对象都复制到该区域,之后直接清空另一块区域。

     5、eden区的对象都有年龄。每熬过经历一次gc,年龄加1. 熬过一定次数的gc,就可以进入老年代,也叫晋级(这个次数默认是15次)。

 

      虚拟机提供了一个参数 MaxTenuringThreshold,来控制晋级的年龄。但是这个参数只是充分非必要条件。也就是说,达到这个年龄,会一定晋升。不到这个年龄,也可能晋升,比如survivor区域满了。这个是JVM根据运行时的survivor区的使用情况动态算出来的。

计算晋升年龄的基本逻辑代码如下:

//TargetSurvivorRatio是from或to的使用率
size_t desired_survivor_size = (size_t) ((((double) survivor_capacity) * TargetSurvivorRatio) / 100);
size_t total = 0;
int age = 1;

//sizes数组保存了每个年龄的对象之和,比如sizes[1]是所有年龄为1的对象大小之和
assert(sizes[0] == 0, "no objects with age zero should be recorded");
while(age < table_size) {
  total += sizes[age];
  if (total > desired_survivor_size) break;
  age++;
}
int result = age  < MaxTenuringThreshold ? age : MaxTenuringThreshold;

 

 

五、TLAB简介

全称叫Thread Local Allocation Buffer,即线程本地分配缓存。

是因为对象一般分配在堆上,堆是全局共享的。所以在同一时间,可能有很多线程在堆上申请空间。每次分配都必须同步,竞争激烈的情况下,分配对象的效率会进一步下降。

所以为了提高分配的效率,使用TLAB这种线程专属的区域避免多线程冲突。而TLAB本身是在Eden上。

    
 

 

  • 大小: 22.5 KB
  • 大小: 6.7 KB
分享到:
评论

相关推荐

    垃圾回收算法与实现

    综上所述,《垃圾回收的算法与实现》这本书不仅涵盖了垃圾回收的理论知识,还结合了实际编程语言中的具体实现,为读者提供了全面了解和掌握垃圾回收技术的途径,是一本难得的专业技术图书。通过本书,读者能够深入...

    Python垃圾回收机制

    这是最基础的垃圾回收策略,它为每个对象维护一个引用计数器,记录有多少个引用指向这个对象。当对象的引用计数变为0时,表示没有变量再使用这个对象,垃圾回收器就会回收这块内存。但这种机制对循环引用(两个或更...

    JVM入门实战/arthas实战/垃圾回收算法/垃圾回收器/jvm内存模型分析

    4、基础知识讲解透彻、详尽; 5、JVM零基础也能听懂。 第一节:学习JVM的意义和目标 1.1 意义: 1.2 目标: 第二节:JVM内存模型 1.1 概念 1.2 JVM内存模型 1.3 Heap堆内存模型 第三节:定位垃圾对象的依据 1.1...

    Java Garbage Collection Basics

    # Java垃圾回收基础知识详解 ## 引言 Java 虚拟机 (JVM) 的垃圾回收机制是 Java 语言的一项重要特性,它自动管理内存,帮助开发者减轻了手动管理内存的压力。本篇将深入探讨 Java 垃圾回收的基本原理、工作方式...

    java垃圾回收技术,面试会问

    #### 二、基础知识 ##### 2.1 对象与垃圾 在Java中,当使用`new`关键字创建对象时,系统会在堆内存中分配一块空间用于存储该对象。例如: ``` Dog d = new Dog(); ``` 这里,`d`变量指向了一个新创建的`Dog`对象。...

    垃圾回收分类查询平台微信小程序端

    通过以上技术,【垃圾回收分类查询平台微信小程序端】实现了便捷的垃圾分类查询功能,不仅提高了用户的垃圾分类知识,也为环保事业贡献了一份力量。开发者在实践中不断提升技术水平,同时也为用户提供了更高效、易用...

    JVM内存分配与垃圾回收详解

    JVM 内存分配与垃圾回收详解 Java 虚拟机(JVM)是 Java 语言的 runtime 环境,它提供了一个平台独立的方式来执行 Java 字节码。...了解 JVM 内存分配与垃圾回收是 Java 开发者必须掌握的基础知识之一。

    Java_GC垃圾回收调优指南

    #### Java GC基础知识 垃圾回收是一种自动化的内存管理机制,它负责回收不再使用的对象所占用的内存空间。Java虚拟机(JVM)内置了高效的垃圾回收器来执行这项任务。不同的垃圾回收策略适用于不同场景下的应用程序...

    构建建筑垃圾回收循环利用APP的设想.pdf

    【标题】:构建建筑垃圾回收循环利用APP的设想 【描述】:该文档提出了一个关于构建建筑垃圾回收循环利用应用程序(APP)的概念,旨在解决建筑垃圾处理的问题,推动循环经济和绿色经济的发展。 【标签】:APP应用...

    垃圾回收机制文件打包

    在Java编程语言中,垃圾回收(Garbage Collection, GC)是...本压缩包中的文件可能涵盖了这些主题的详细讲解,包括理论知识、实践案例和性能调优技巧,对于希望深入理解Java垃圾回收机制的开发者来说是一份宝贵的资料。

    JVM的工作原理及垃圾回收机制介绍

    判断一个对象是否已经死亡是垃圾回收的基础。主要有两种方法: - **引用计数法**:给每个对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数值减1。当计数器为0时,对象可以被回收...

    垃圾回收物流仿真系统设计(DOC 37).zip

    在垃圾回收物流仿真系统设计中,我们探讨的核心是利用计算机技术模拟实际的垃圾收集、运输和处理流程,以便优化资源分配、提高效率并减少环境影响。这个系统的设计涵盖了多个IT领域的知识,包括软件工程、数据结构、...

    java入门、java内存区域和OOM、垃圾回收器和垃圾回收策略

    本教程将涵盖Java的基础知识,特别是关于内存管理的重要概念——Java内存区域、Out of Memory (OOM)错误以及垃圾回收器和垃圾回收策略。 1. **Java入门**: Java的学习始于基础语法,包括变量、数据类型、运算符、...

    高吞吐低延迟Java应用的垃圾回收优化.docx

    Java 应用垃圾回收优化 垃圾回收优化是 Java 应用的关键性能指标之一。对高吞吐低延迟 Java 应用的垃圾回收优化是确保用户体验的重要一步。LinkedIn 的高吞吐量服务需要低延迟地响应用户请求,动态信息数据平台作为...

    用模板实现的C++垃圾回收器.zip

    1. "GarbageCollector1Operation.rar":这可能是基础版或第一个版本的垃圾回收器实现,专注于基本的垃圾收集操作。 2. "GarbageCollectVerMThread.rar":这个名字暗示了这是一个多线程版本的垃圾回收器。在多线程...

    详细介绍Java垃圾回收机制

    了解这些基础知识后,开发者可以更好地理解和调整JVM的垃圾回收行为,以优化应用程序的性能和内存使用。例如,选择合适的垃圾收集器、调整JVM参数、理解和避免内存泄漏,都是提升Java应用性能的重要手段。随着Java...

    重要:虚拟机垃圾回收图

    本篇文章将深入探讨“虚拟机垃圾回收图”及相关知识点。 首先,我们关注的是Java内存模型,它主要分为五个区域:程序计数器、虚拟机栈、本地方法栈、堆和方法区(在Java 8之后被元空间取代,但这里仍沿用传统术语)...

    垃圾分类基础知识竞赛试题(中小学生必会).docx

    ### 垃圾分类基础知识竞赛试题知识点解析 #### 一、垃圾分类基础知识概述 垃圾分类是指将垃圾按照一定标准或特性分成不同类别,以便更好地进行回收利用和处理的一种方式。正确进行垃圾分类不仅有助于环境保护,还...

    Golang 垃圾回收面试宝典!

    我分享了一份Golang垃圾回收面试宝典,该宝典涵盖了Golang垃圾回收的基础知识、运行时机制、算法实现、调优等方面,旨在帮助读者更好地了解和掌握Golang垃圾回收相关知识。如果你正在为Golang垃圾回收面试而烦恼,...

    Java基础复习笔记02对象状态、引用种类、垃圾回收形式.doc

    了解这些基础知识,可以帮助Java开发者编写出更高效、更稳定的代码,特别是在资源有限或需要优化性能的环境中。例如,合理使用不同类型的引用可以控制对象的生命周期,避免内存泄漏,同时理解和掌握垃圾回收的工作...

Global site tag (gtag.js) - Google Analytics