GC(Garbage Collection)垃圾回收机制

1、在垃圾回收器中,程序员没有执行权,只有通知它的权利。

2、程序员可以通过System.gc()。通知GC运行,但是Java规范并不能保证立刻运行。

3、finalize()方法,是java提供给程序员用来释放对象或资源的办法,但是尽量少用。

一、GC的介绍 
GC的全称是Garbage Collection (垃圾收集) 
在GC中,垃圾所指的是程序在运行过程中,会产生出一些无用的对象,或者说是已经被弃用的对象,而这些对象会占用着一部分的内存空间,如果长时间不去回收这些内存空间,那么最终会导致OOM(内存泄漏)。 
在内存区域中,有三个区域,分别是:程序计数器,虚拟机栈,本地方法栈。这三个区域和线程是紧密相连的。

二、GC的性能 
通常对GC性能的评定,考虑GC的性能优劣,基本上要从三方面着手:吞吐量,延迟,内存。

三、三大简单GC算法

  1)标记清除算法:标记算法的原理是非常简单的,首先我们从根(root)开始对可能被引用的对象用递归的方式进行标记,而未被标记的对象就是我们应当去回收的对象,

  • 如下图所示: 

    注意:标记清除算法有一个非常严重的问题:内存碎片化。
  • 2)复制收集算法:复制收集算法是在内存碎片化问题上的一种解决办法,在复制收集算法中,会把从根(Root)开始被引用的对象复制到另外的空间中,最终会有一个空间内存放着所有不需被清除的对象,并且它们的内存是连续的。如下图所示: 

    注意:虽然这可以很好的解决内存碎片化,但是却引发另外的内存空间,使得复制收集算法需要高成本的内存,因为它需求的内存大小是原内存的两倍。
  • 3)引用计数算法:引用计数的算法和标记清除的方式其实有些类似,原理是在每个对象中保存该对象被引用次数,引用数有变化时进行更新,而一个对象的引用数为0,说明该对象是弃用的,应当被回收。如下图所示: 

    注意:引用计数算法是无法释放循环引用的对象的,如下图所示,无法正常计数: 

四、三大高级GC算法 
上面提及的三大简单GC算法是GC的基本算法,而三大高级GC算法是结合三种方式的高级GC算法。这三大高级GC算法是:分代回收,增量回收,并行回收。

五、GC的分代回收 
GC将对象数据进行分类。主要是两类:年轻代(Young Generation),老年代(Old Generation)。

年轻代(Young Generation):通常最新被创建的对象会被分配在这里,而大多数对象会很快的变得不可达,因此,很多对象会在被成年轻代之后就消失,而这个过程我们称之为“ minor GC”

老年代(old Generation):对象来自新生代,如上所说部分对象会不可达,而剩下的从年轻代中存活下来,被拷贝至老年代。老年代所占用的空间要比年轻代多。如上,对象在老年代也会消失,而这个过程被称之为“major GC”(或者是 “full GC”).

Permanebt Generation :持久代,或者称为方法区(method area),通常持久代用来保存类常量以及字符串常量。而特别需要注意这个持久代区域不是用来保存从老年代存活下来的对象的。持久代也可以发生GC。同时这个区域的GC会被看待为 major GC.

下面简单聊聊年轻代的结构组成,年轻代含两种结构,伊甸园空间(1个)和幸存者空间(2个)。 
年轻代遵循以下规则:

  • 通常刚刚被创建的对象会存放在伊甸园空间。
  • 伊甸园空间执行GC后,存活着的对象会被转移至其中一个幸存者空间中。
  • 此后,在伊甸园空间执行GC之后,存活的对象会被堆积在同一个幸存者空间。
  • 若一个幸存者空间已经饱和了,那么存活的对象就会保存至另一个幸存者空间内,并且之后的操作会去清空之前那个已饱和的幸存者空间。
  • 执行GC多次后,依然存活的对象会被转移至老年代。

而老年代方面,对象在年轻代存活的时间足够长,并且没有被清理掉,那么最终会复制到老年代,注意:老年代的存储空间要比年轻代大,可以存放更多的对象,不过老年代执行GC的次数要比年轻代少,当老年代存储空间不够时,那么就会执行GC,这个GC叫做major Gc,也叫 full GC 。

另外的就是永久代(方法区): 
永久代主要回收两种:常量池中的常量,无用的类信息。 
要知道常量的回收是相对简单的,主要是无用的类回收比较麻烦,要注意以下几点:

  • 类的实例已经全部被回收了
  • ClassLoader已经被回收
  • 类的对象没有被引用

伊甸区的大部分对象都是刚被分配的,而幸存区用来存储的是从伊甸区内幸存下来的对象,伊甸区和幸存区组成了“年轻代

六、增量回收 
要知道GC的执行本身是耗时间占内存的,并且GC本身执行的时间上是具有不确定性的,在GC执行过程中,会中断其他程序的执行。在对实时性要求高的程序中,是非常重视GC的最大中断时间的,所以有必要将GC的执行“分段”,这种回收方式就是增量回收。在增量回收的过程中,GC的执行是渐进的,在回收过程中,程序本身是继续运行的,在这个过程中对象的引用关系可能也会改变。如果已经完成扫描和标记的对象被修改了,对新的对象产生了引用,这个新的对象就不会被标记。在增量回收过程中,为了解决这个问题,我们需要使用写屏障,在标记的对象的引用关系发生变化时,使用写屏障会将被引用的对象作为扫描的起始点记录下来。当然,增量回收也会有遗留问题存在:中断操作需要消耗一定的时间,GC所消耗的总时间也会随之增加。

七、并行回收 

这就好比如今的计算机,多核CPU处理方式,这是提升计算机运行速度的一种手段,例如生活中,我们可以边走路,边打电话,而不是打电话的时候停下来不走路,也不是走路的时候挂电话。因为在环境允许的情况下,很多事是可以同时做的,多核CPU就可以并行处理多个任务。并行回收的原理就是所有程序运行的同时执行GC操作。不过,要记住一点,要让GC完全和其他程序并行操作,并且一点都不互相影响执行速度,这基本是做不到的,总的来说,在GC执行到某个特定阶段时,是需要停止其他程序的运行的。

八、GC的特点 

需要回收的对象必须要回收,不该回收的对象一定不能回收。回收所消耗的时间必须要尽可能少,因为回收机制本身就是要消耗内部资源的,因此,我们必须要在时间,空间,效率上都要考虑到。要知道在内存碎片问题、可伸展性、可伸缩性方面考虑,我们可以针对性的选择不同的垃圾回收器。

九、GC自身的初始化 
GC是一个自动执行的进程,所以Java并不会去要求开发者去主动初始化GC,在Java中有 system.gc()和 Runtime.gc() 可以hook,请求JVM调用GC进程。JVM是具备选择拒绝启动GC的请求的能力的,所以有请求未必就有真正的调用GC。那么JVM是怎么去决定的呢?事实上,JVM会根据内存空间的Eden区(下文会讲解Eden区)的使用情况做出正确的判断。

十、GC的基本原理 
对于GC来说,对象从被创建时,GC就开始了对对象的监控,包括对象的地址,对象的大小,以及对象的使用情况。GC常常是采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式来判断对象的“可达”与“不可达”。当对象变得“不可达”后,GC将会负责回收“不可达”对象的内存空间。注意:不同的JVM要用不同的回收算法。

下面讲讲一些相关的垃圾回收算法:

  • 标记清除算法:标记可以被回收的内存,然后进行回收处理,而标记-清除算法是有两阶段的,一是标记,二是清除。
  • 复制算法:将内存按容量分为两块,例如A、B两块,每次只使用其中的一块,当要进行回收操作时,将A中还存活的对象复制到B块中(假设上次使用A),然后对A中所有对象清空就又构成一个完整的内存块。
  • 标记整理法:标记整理法就是在标记清除方法上进行的优化,主要是在标记完成后将这些存活的对象向一端移动,然后将末尾边界后的所有内存空间清除。
  • 火车回收算法:在火车算法中,内存被分为块,多个块组成一个集合。为了形象化,一节车厢代表一个块,一列火车代表一个集合。注意每个车厢大小相等,但每个火车包含的车厢数不一定相等。垃圾收集以车厢为单位,收集顺序按被创建的先后顺序进行。

十一、关于全局暂停事件 
在GC执行过程中,程序的暂停被称为“全局暂停事件”,为了进行垃圾回收,是不得不这么做的。针对算法的不同,收集器的不同,全局暂停事件可能会在不同时间或者不同地方暂停程序。而为了完全停止程序,则需要暂停所有运行中的线程。

时间: 2024-10-09 11:58:17

GC(Garbage Collection)垃圾回收机制的相关文章

JavaScirpt 的垃圾(garbage collection)回收机制

一.垃圾回收机制—GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存. JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行. 不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生

An Introduction to Garbage Collection(垃圾回收简介)

1. Introduction 2. Principles 3. Advantages 4. Disadvantages 5. 常见的垃圾回收技术 5.1. 跟踪式垃圾回收 5.1.1. 基本算法 5.2. 引用计数垃圾回收 5.3. 分代垃圾回收 5.4. 对象使用类型分析 6. 参考 团队项目中用Go的地方越来越多,最近打算在业余时间好好看看Golang的虚拟机实现.像Java/C#/Python一样,Go的优势之一就是将开发人员从繁重的内存管理中解放 出来,本文对编程语言中常见的垃圾回收技

Android内存优化1 了解java GC 垃圾回收机制3

引言 接App优化之内存优化(序), 作为App优化系列中内存优化的一个小部分. 由于内存相关知识比较生涩, 内存优化中使用到的相关工具, 也有很多专有名词. 对Java内存管理, GC, Android内存管理, Dalvik/ART等知识有一个理论的认识, 可以让我们更好的使用这些工具, 分析内存问题. 据此, 我们就先从理论入手, 聊聊GC那些事儿. 1, 何为GC GC 是 garbage collection 的缩写, 垃圾回收的意思. 也可以是 Garbage Collector,

C# GC 垃圾回收机制

今天来谈谈C# 的GC ,也就是垃圾回收机制,非常的受教,总结如下 首先:谈谈托管,什么叫托管,我的理解就是托付C# 运行环境帮我们去管理,在这个运行环境中可以帮助我们开辟内存和释放内存,开辟内存一般用new ,内存是随机分配的,释放主要靠的是GC 也就是垃圾回收机制.哪么有两个大问题 1.GC 可以回收任何对象吗?2.GC 什么时候来回收对象?回收那些对象? 对于第一个问题,GC 可以回收任何对象吗?我是这样理解的,首先要明白一点,C# 在强大也管不到非托管代码?哪么什么是非托管代码呢?比如s

php--session垃圾回收机制

在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾.PHP会将其在内存中销毁:这是PHP的GC垃圾处理机制,防止内存溢出. GC的工作就是扫描所有的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,如果生存时间超过gc_maxlifetime(默认24分钟),就将该session删除. 当一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor

用户登录之7天免登陆(垃圾回收机制)

//设置垃圾回收机制ini_set('session.gc_probability','1'); ini_set('session.gc_divisor','1'); Config::set('session.expire',3600*24*7); session.gc_divisor 与 session.gc_probability 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率.此概率用 gc_probability/gc_divisor

java 垃圾回收机制和调优(转)Java Garbage Collection

(转)http://www.cnblogs.com/shudonghe/p/3457990.html 文主要介绍,JVM的组件,自动垃圾收集器是如何工作的,分代垃圾收集器的收集过程,使如何用Visual VM来监视应用的虚拟机,以及JVM中垃圾收集器的种类. 一.JVM架构 1.HotSpot 架构 HotSpot JVM架构支持较强的基本特征和功能,此外还支持高性能和高吞吐率的特性.例如,JVM JIT编译器产生动态优化的代码,亦即,编译器是在Java运行的时候的时候进行优化,并为当然的系统架

垃圾回收机制GC知识再总结兼谈如何用好GC(其他信息: 内存不足)

来源 一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: 1.手动管理:C,C++ 2.计数管理:COM 3.自动管理:.NET,Java,PHP,GO- 但是,手动管理和计数管理的复杂性很容易产生以下典型问题: 1.程序员忘记去释放内存 2.应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱码,而且大部分时候,

垃圾回收机制GC知识再总结兼谈如何用好GC

一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: 1.手动管理:C,C++ 2.计数管理:COM 3.自动管理:.NET,Java,PHP,GO… 但是,手动管理和计数管理的复杂性很容易产生以下典型问题: 1.程序员忘记去释放内存 2.应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱码,而且大部分时候,程序的

Java垃圾回收机制(GC)详解

Java垃圾回收机制(GC)详解 简介: 垃圾回收GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变.垃圾收集的目的在于清除不再使用的对象.GC通过确定对象是否被活动对象引用来确定是否收集该对象.GC首先要判断该对象是否是时候可以收集.两种常用的方法是引用计数和对象引用遍历. 垃圾收集的算法分析: Java语言规范没有明确地说明JVM使用哪种垃圾