go java gc_图解Golang的GC垃圾回收算法

虽然Golang的GC自打一开始,就被人所诟病,但是经过这么多年的发展,Golang的GC已经改善了非常多,变得非常优秀了。

以下是Golang GC算法的里程碑:

v1.1 STW

v1.3 Mark STW, Sweep 并行

v1.5 三色标记法

v1.8 hybrid write barrier

经典的GC算法有三种: 引用计数(reference counting) 、 标记-清扫(mark & sweep) 、 复制收集(Copy and Collection) 。

Golang的GC算法主要是基于 标记-清扫(mark and sweep) 算法,并在此基础上做了改进。因此,在此主要介绍一下 标记-清扫(mark and sweep)算法 ,关于 引用计数(reference counting) 和 复制收集(copy and collection) 可自行百度。

标记-清扫(Mark And Sweep)算法

此算法主要有两个主要的步骤:

标记(Mark phase)

清除(Sweep phase)

第一步,找出不可达的对象,然后做上标记。

第二步,回收标记好的对象。

操作非常简单,但是有一点需要额外注意: mark and sweep 算法在执行的时候,需要程序暂停!即 stop the world 。

也就是说,这段时间程序会卡在哪儿。故中文翻译成 卡顿 。

我们来看一下图解:

开始标记,程序暂停。程序和对象的此时关系是这样的:

a88cd4a0a554f723067baf315e3846e0.png

然后开始标记,process找出它所有可达的对象,并做上标记。如下图所示:

1a6fa3925974b458c21e5daba0ad7cd8.png

标记完了之后,然后开始清除未标记的对象:

5b68a9effb2fb5ca365150a71d6ca20c.png

然后 垃圾 清除了,变成了下图这样。

29ceef05cdce940a14a6967b30bf917c.png

最后,停止暂停,让程序继续跑。然后循环重复这个过程,直到 process 生命周期结束。

标记-清扫(Mark And Sweep)算法存在什么问题?

标记-清扫(Mark And Sweep)算法 这种算法虽然非常的简单,但是还存在一些问题:

STW,stop the world;让程序暂停,程序出现卡顿。

标记需要扫描整个heap

清除数据会产生heap碎片

这里面最重要的问题就是:mark-and-sweep 算法会暂停整个整个程序。

Go是如何面对并这个问题的呢?

三色并发标记法

我们先来看看Golang的三色标记法的大体流程。

首先:程序创建的对象都标记为白色。

f67076d05f93d91720d1524365911097.png

gc开始:扫描所有可到达的对象,标记为灰色

cb67c8da24be7cc0f113f983b7461b60.png

从灰色对象中找到其引用对象标记为灰色,把灰色对象本身标记为黑色

290c706c97fe8476fc23c8c2b2df72bc.png

监视对象中的内存修改,并持续上一步的操作,直到灰色标记的对象不存在

033a9261cf9c9b5b1c9d436e095c3f96.png

此时,gc回收白色对象。

c567fcdcd8907709b3abb3a55d73118a.png

最后,将所有黑色对象变为白色,并重复以上所有过程。

73e450bd17ecf7b9a98e82a7568800e1.png

好了,大体的流程就是这样的,让我们回到刚才的问题:Go是如何解决 标记-清除(mark and sweep) 算法中的卡顿(stw,stop the world)问题的呢?

gc和用户逻辑如何并行操作?

标记-清除(mark and sweep)算法的STW(stop the world)操作,就是runtime把所有的线程全部冻结掉,所有的线程全部冻结意味着用户逻辑是暂停的。这样所有的对象都不会被修改了,这时候去扫描是绝对安全的。

Go如何减短这个过程呢?标记-清除(mark and sweep)算法包含两部分逻辑:标记和清除。

我们知道Golang三色标记法中最后只剩下的黑白两种对象,黑色对象是程序恢复后接着使用的对象,如果不碰触黑色对象,只清除白色的对象,肯定不会影响程序逻辑。所以: 清除操作和用户逻辑可以并发。

标记操作和用户逻辑也是并发的,用户逻辑会时常生成对象或者改变对象的引用,那么标记和用户逻辑如何并发呢?

process新生成对象的时候,GC该如何操作呢?不会乱吗?

我们看如下图,在此状态下:process程序又新生成了一个对象,我们设想会变成这样:

35bc560be6cd4fefcd6a82a6af760776.png

但是这样显然是不对的,因为按照三色标记法的步骤,这样新生成的对象A最后会被清除掉,这样会影响程序逻辑。

Golang为了解决这个问题,引入了 写屏障 这个机制。

写屏障:该屏障之前的写操作和之后的写操作相比,先被系统其它组件感知。

通俗的讲:就是在gc跑的过程中,可以监控对象的内存修改,并对对象进行重新标记。(实际上也是超短暂的stw,然后对对象进行标记)

在上述情况中, 新生成的对象,一律都标位灰色!

即下图:

5515639647c55c5d8da5f901aeb0e1af.png

那么,灰色或者黑色对象的引用改为白色对象的时候,Golang是该如何操作的?

看如下图,一个黑色对象引用了曾经标记的白色对象。

7ce802d8e4d378c140c04b284105c3f1.png

这时候,写屏障机制被触发,向GC发送信号,GC重新扫描对象并标位灰色。

b7c30f6ef3070212e1ecf18e97df3baf.png

因此,gc一旦开始,无论是创建对象还是对象的引用改变,都会先变为灰色。

参考文献:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574649.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

统计学的经典书籍指南 (转载自:http://blog.csdn.net/ysuncn/article/details/1943679)...

一、统计学基础部分 1、《统计学》 David Freedman等著,魏宗舒,施锡铨等译 中国统计出版社 据说是统计思想讲得最好的一本书,读了部分章节,受益很多。整本书几乎没有公式,但是讲到了统计思想的精髓。 2、《Mind on …

Linux Bash Shell j简单入门

BASH 的基本语法 最简单的例子 —— Hello World! 关于输入、输出和错误输出 BASH 中对变量的规定(与 C 语言的异同) BASH 中的基本流程控制语法 函数的使用 2.1 最简单的例子 —— Hello World! 几乎所有的讲解编程的书给读者的第一个例子都是 …

jpa mysql脚本迁移_JPA通过LOAD DATA LOCAL INFILE大批量导入数据到MySQL

连接层代码:import org.hibernate.Session;import org.hibernate.internal.SessionFactoryImpl;import org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLE…

javascript的事件冒泡,阻止事件冒泡和事件委托, 事件委托是事件冒泡的一个应用。...

2018年12月13日更新 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>ul li{border: 1px solid yellow;}</style> </head> <body> <p hidden>…

php 序列化 java_PHP--序列化与反序列化详解

PHP--序列化与反序列化详解博客说明文章所涉及的资料来自互联网整理和个人总结&#xff0c;意在于个人学习和经验汇总&#xff0c;如有什么地方侵权&#xff0c;请联系本人删除&#xff0c;谢谢&#xff01;说明所有php里面的值都可以使用函数serialize()来返回一个包含字节流的…

hadoop2.x的变化

HDFS Federation&#xff08;HDFS联邦&#xff09; HDFS有两个主要层&#xff1a; Namespace 由目录、文件和块组成&#xff1b;支持所有命名空间对文件和目录的操作。 Block Storage Service 由Block Management和Storage组成。 Block Management 提供dataNode集群成员关系&am…

python enumeration_python枚举防止无效的属性分配

要使枚举类完全“只读”,只需要使用__setattr__hook防止全部的属性分配。因为元类附加到类之后它是创建的,分配正确的枚举值没有问题。就像伊桑的回答一样,我用的是EnumMeta类作为自定义元类的基础:from enum import EnumMeta, Enumclass FrozenEnumMeta(EnumMeta):"Enum …

java wps linux 安装_ubuntu安装Java开发环境

1. 从sun主页JDK for Linux版本。这里的是jdk-6u6--i586.bin.2. 用root用户登录ubuntu&#xff0c;或是在普通用户下用su命令切换用户。切换到所需的安装目录。类型&#xff1a;cd 例如&#xff0c;要在 /usr/java/ 目录中 安装软件&#xff0c;请键入&#xff1a;cd /usr…

[BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】

题目链接&#xff1a;BZOJ - 2594 题目分析 这道题如果没有删边的操作&#xff0c;那么就是 NOIP2013 货车运输&#xff0c;求两点之间的一条路径&#xff0c;使得边权最大的边的边权尽量小。 那么&#xff0c;这条路径就是最小生成树上这两点之间的路径。 然而现在有了删边操作…

vs升级c++项目遇到的一些问题

1、error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended. 在工程的stdafx.h中&#xff0c;改为如下配置&#xff1a; #ifndef WINVER #define WINVER 0x0501 #endif #ifndef _WIN32_WINNT #def…

python模糊匹配忽略大小写_在python中忽略大小写的简单方法?

如果搜索多个单词&#xff0c;则创建一个集合是有意义的&#xff1a;print(set(brown_sents).intersection(zip(repeat(most_ambiguous_word),word_class_dict[most_ambiguous_word])))输出{(word2, wordclass2), (word2, wordclass3)}要理解它的作用&#xff0c;请将脚本保存到…

IAR7.51提示秘钥无效IAR 以及 CCDebug驱动(包含win7 64bit)

今天IAR不识别我的仿真器&#xff0c;然后我感觉驱动有问题&#xff0c;就把之前的驱动卸载了&#xff0c;但是按照以前的方法按章驱动(选择路径到IAR的某个目录)&#xff0c;提示找不到驱动。。。 也不想重新装个IAR了&#xff0c;于是到CSDN上下载了这个驱动程序&#xff0c;…

cannot be resolved or is not a field

我通常的解决办法&#xff1a;1.看看是不是manifest.xml文件有错误&#xff0c;如果有的话&#xff0c;R.java是不会生成的2.一般来说R.layout.aaa.xml&#xff0c;这里的R是自己的包的R.java&#xff0c;不是android系统的R.java&#xff0c;所以如果引入包的时候有import and…

java解析时已到达文件结尾_IO流读取到文件末尾继续读取

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;//正常情况//main()方法中第一个read()和和第二个read();是可以顺利执行完的…

百度地图动态显示查询结构

<script type"text/javascript">// 百度地图API功能function G(id) {return document.getElementById(id);}var map new BMap.Map("l-map");map.centerAndZoom("北京",12); // 初始化地图,设置城市和地图级别。var ac …

solr5.0mysql_ik扩展支持Solr配置详解

扩展ik原生代码&#xff1a;public class IKAnalyzerTokenizerFactory extends TokenizerFactory{private boolean useSmart;public boolean useSmart(){return this.useSmart;}public void setUseSmart(boolean useSmart) {this.useSmart useSmart;}public IKAnalyzerTokeniz…

apache htpasswd.exe创建密码

一、使用apache htpasswd.exe创建密码文件&#xff0c;命令请看PHP推荐教程&#xff1a;apache htpasswd命令用法详解 apache htpasswd命令用法实例 1、如何利用htpasswd命令添加用户&#xff1f; 在apache安装目录bin下找到htpasswd #usr/local/apache/bin/htpasswd -bc .pass…

考研复试考java_2019考研复试经验帖:过来人谈5件“小事”

关于复试&#xff0c;决定这你的命运&#xff0c;考生一定要好好把握。关于复试&#xff0c;你做好前期功课&#xff0c;足够了解了吗?下面新东方在线分享一位过来人的经验之谈&#xff0c;给大家最走心的忠告~~▶先来说说复试规则。在复试之前学校会公布学校的复试分数线&…

Hadoop2源码分析-RPC机制初识

1.概述 上一篇博客&#xff0c;讲述Hadoop V2的序列化机制&#xff0c;这为我们学习Hadoop V2的RPC机制奠定了基础。RPC的内容涵盖的信息有点多&#xff0c;包含Hadoop的序列化机制&#xff0c;RPC&#xff0c;代理&#xff0c;NIO等。若对Hadoop序列化不了解的同学&#xff0c…

svn客户端 java_svn纯java客户端SVNKit学习整理(转)

http://www.iteye.com/topic/688217http://blog.csdn.net/feiren127/article/details/7551782把svnkit.jar添加到项目中&#xff0c;用于实现svn功能。 把jackson-all-1.6.2.jar添加到项目中&#xff0c;用于显示树列表。把javaee.ar添加到项目中。新建一个类(SVNUtil.class)实…