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执行过程中,程序的暂停被称为“全局暂停事件”,为了进行垃圾回收,是不得不这么做的。针对算法的不同,收集器的不同,全局暂停事件可能会在不同时间或者不同地方暂停程序。而为了完全停止程序,则需要暂停所有运行中的线程。
GC(Garbage Collection)垃圾回收机制的更多相关文章
- JVM-5-GC(Garbage Collection) 垃圾回收机制
GC(Garbage Collection) 垃圾回收机制 什么是垃圾回收机制 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能. ...
- 【python进阶】Garbage collection垃圾回收1
前言 GC垃圾回收在python中是很重要的一部分,同样我将分两次去讲解Garbage collection垃圾回收,此篇为Garbage collection垃圾回收第一篇,下面开始今天的说明~~~ ...
- 【python进阶】Garbage collection垃圾回收2
前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...
- JavaScirpt 的垃圾(garbage collection)回收机制
一.垃圾回收机制—GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性 ...
- An Introduction to Garbage Collection(垃圾回收简介)
1. Introduction 2. Principles 3. Advantages 4. Disadvantages 5. 常见的垃圾回收技术 5.1. 跟踪式垃圾回收 5.1.1. 基本算法 5 ...
- 乐字节Java|GC垃圾回收机制、package和import
本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...
- CSIC_716_20191101【编程语言、变量、垃圾回收机制】
编程语言分类:机器语言.汇编语言.高级语言. 机器语言:机器能直接识别的程序语言或指令代码(二进制指令),勿需经过翻译,每一操作码在计算机内部都有相应的电路来完成它 汇编语言:比机器语言略高级,用英文 ...
- Android内存优化5 了解java GC 垃圾回收机制3
引言 接App优化之内存优化(序), 作为App优化系列中内存优化的一个小部分. 由于内存相关知识比较生涩, 内存优化中使用到的相关工具, 也有很多专有名词. 对Java内存管理, GC, Andro ...
- Android内存优化3 了解java GC 垃圾回收机制1
开篇废话 如果我们想要进行内存优化的工作,还是需要了解一下,但这一块的知识属于纯理论的,有可能看起来会有点枯燥,我尽量把这一篇的内容按照一定的逻辑来走一遍.首先,我们为什么要学习垃圾回收的机制,我大概 ...
- C# GC 垃圾回收机制
今天来谈谈C# 的GC ,也就是垃圾回收机制,非常的受教,总结如下 首先:谈谈托管,什么叫托管,我的理解就是托付C# 运行环境帮我们去管理,在这个运行环境中可以帮助我们开辟内存和释放内存,开辟内存一般 ...
随机推荐
- Loadrunner脚本篇——从文件中读取内容并参数化
直接代码展示: char* testfn() { int count, total = 0; char * buffer = NULL; int filelenth = 0; long file_st ...
- iOS 4.5.5版本 被拒绝!!!! "App Rejected : non-public APIs"
今天上午收到邮件说是被拒绝了 原文是 这一版本 我就添加一个购买sku的方法, 并没有添加什么库 ,简简单单的一次升级给我出一私有方法拒绝!!!!! 在xcode8 iOS10 刚出来 ,苹果新规则 ...
- c# 内部类使用接口IComparer实现排序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- $git学习总结系列(2)——远程仓库
本文主要介绍git本地仓库和GitHub远程仓库之间的交互和数据传输. 注:首先需要到github.com上注册一个账号. 1. 添加本地SSH Key到GitHub 要向GitHub远程仓库推送代码 ...
- HTTP学习笔记01-URL
URI URL语法 相对URL和绝对URL 相对URL URL的常用协议 http https mailto ftp rtsprtspu file news telnet 展望美好的未来 1.URI ...
- Java开发者或许应该经常去看看的网站?...
Java开发者或许应该经常去看看的网站?...Google top3 1.Oracle Technology Network for Java Developers | Oracle Technolo ...
- 【Flask】Flask-Sqlalchemy使用笔记
### 安装:```shellpip install flask-sqlalchemy``` ### 数据库连接:1. 跟sqlalchemy一样,定义好数据库连接字符串DB_URI.2. 将这个定义 ...
- Cocos2d-x项目移植到WP8系列之五:播放MP3
原文链接: http://www.cnblogs.com/zouzf/p/3972549.html 这一块的细节还是不太了解,只是东凑西拼能跑起来而已 1.网上下载lamb库 生成需要的lib库,详情 ...
- Java -- 数据库 多表操作,1对多,多对多,1对1。 基于dbutils框架
1. 1对多,部门--员工 为例, 多的一方建外键. domain,建立bean对象 public class Department { private String id; private Stri ...
- Linux嵌入式 -- 内核 - 系统调用
1. 系统调用 定义 Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用.用户可以通过系统调用命令在自己的应用程序中调用它们. 系统调用和普通的函数调用非常相似,区别仅仅在于,系统调 ...