垃圾回收算法以及垃圾回收器_什么是垃圾回收?

垃圾回收算法以及垃圾回收器

以下是我们的垃圾收集手册中的一个示例,该手册将在接下来的几周内发布。 同时,花点时间熟悉垃圾收集的基础知识-这将是本书的第一章。

乍一看,垃圾收集应该处理顾名思义的问题–查找并丢弃垃圾。 实际上,它所做的恰恰相反。 垃圾收集正在跟踪所有仍在使用的对象,并将其余对象标记为垃圾。 牢记这一点,我们开始深入研究如何为Java虚拟机实现称为“垃圾回收”的自动内存回收过程。

手动内存管理

在我们以现代形式开始介绍Garbage Collection之前,让我们快速回顾一下过去,您不得不手动,显式分配和释放数据存储空间。 而且,如果您忘记释放它,则将无法重用该内存。 该内存将被声明但未被使用。 这种情况称为内存泄漏

这是一个使用C语言编写的,使用手动内存管理的简单示例:

int send_request() {size_t n = read_size();int *elements = malloc(n * sizeof(int));if(read_elements(n, elements) < n) {// elements not freed!return -1;}// …free(elements)return 0;
}

如我们所见,忘记释放内存是很容易的。 内存泄漏曾经是比现在更常见的问题。 您只能通过修复代码来真正打败他们。 因此,更好的方法将是自动回收未使用的内存,从而完全消除人为错误的可能性。 这种自动化称为垃圾收集 (或简称GC)。

智能指针

自动进行垃圾收集的第一种方法是基于引用计数。 对于每个对象,您只知道它被引用了多少次,并且当计数达到零时,就可以安全地回收该对象。 一个众所周知的例子是C ++的共享指针:

int send_request() {size_t n = read_size();stared_ptr<vector<int>> elements = make_shared(new vector<int>());if(read_elements(n, elements) < n) {return -1;}return 0;
}

我们正在使用的shared_ptr会跟踪对其的引用数。 此数字随着您的传递而增加,随着其离开范围而减小。 一旦引用数量达到零, shared_ptr就会自动删除基础向量。

自动内存管理

在上面的C ++代码中,我们仍然必须明确地说出何时需要进行内存管理。 但是,如果我们可以使所有对象以这种方式表现呢? 这将非常方便,因为开发人员可能不再需要考虑自己清理。 运行时将自动了解不再使用某些内存,并将其释放。 换句话说,它会自动收集垃圾 。 1959年,第一个垃圾收集器出现在Lisp那里,从那时起,这项技术才发展起来。

参考计数

我们用C ++的共享指针演示的想法可以应用于所有对象。 许多语言(例如Perl,Python或PHP)都采用这种方法。 最好用图片来说明:

Java GC计数参考1

绿云表示程序员指向的对象仍在使用中。 从技术上讲,这些可能是诸如当前正在执行的方法中的局部变量或静态变量之类的东西。 它可能因编程语言而异,因此在此我们将不再关注。

蓝色圆圈是内存中的对象,您可以看到对其的引用数量。 最后,灰色圆圈是未从任何范围引用的对象。 因此,灰色物体是垃圾,可以由垃圾收集器清理。

这一切看起来真的很好,不是吗? 可以,但是整个方法都有很大的缺点。 结束对象的分离循环是很容易的,这些对象都不在范围内,但是由于循环引用,其引用的计数不为零。 这是一个例子:

Java GC标记和扫描

看到? 红色对象实际上是应用程序不使用的垃圾。 但是由于引用计数的限制,仍然存在内存泄漏。

有一些方法可以克服此问题,例如使用特殊的“弱”引用或应用单独的算法来收集周期。 提到的语言(Perl,Python和PHP)都以一种或另一种方式处理循环,但这超出了本手册的范围。 相反,我们将开始更详细地研究JVM所采用的方法。

扫一扫

首先,JVM更具体地说明了对象的可访问性。 与其在前几章中看到的模糊定义的绿色云,不如我们有一组非常具体和明确的对象,称为“ 垃圾收集根”

  • 局部变量
  • 活动线程
  • 静态场
  • JNI参考
  • 其他(稍后将讨论)

JVM用于跟踪所有可到达(活动)对象并确保可重用非可访问对象声明的内存的方法称为标记和清除算法。 它包括两个步骤:

  • 标记正在遍历所有可到达的对象,并将有关所有此类对象的分类帐保存在本机内存中
  • 扫描确保了不可访问对象占用的内存地址可以在下一次分配中重用。

JVM中的不同GC算法(例如Parallel Scavenge,Parallel Mark + Copy或CMS)在实现这些阶段时略有不同,但是从概念上讲,该过程仍然类似于上述两个步骤。

关于此方法,至关重要的一点是周期不再泄漏:

Java GC计数参考1

不太好的事情是,需要停止应用程序线程以进行收集,因为如果引用线程一直在变化,那么您就无法真正计数它们。 当应用程序暂时停止以使JVM可以沉迷于家政活动时,这种情况称为Stop The World暂停 。 它们的发生可能有多种原因,但是垃圾收集是迄今为止最受欢迎的一种。

如果您能够通过发布获得成功,那么我仅建议您订阅我们的Twitter feed ,在其中继续发布与Java性能相关的其他主题。

翻译自: https://www.javacodegeeks.com/2015/05/what-is-garbage-collection.html

垃圾回收算法以及垃圾回收器

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

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

相关文章

c语言中fgetc函数的介绍

点击上方蓝字关注我&#xff0c;了解更多咨询1、fgetc函数返回的字符实际上是文件流中位置指针指向的字符。当fgetc函数读取错误时&#xff0c;返回EOF并设置文件错误标志位。2、该函数以无符号char强制转换为int的形式返回读取的字符&#xff0c;如果到达文件末尾或出现读错&a…

花5分钟了解C语言基本语法元素快来

点击上方蓝字关注我&#xff0c;了解更多咨询C语言是一种编程语言&#xff0c;和其它语言一样&#xff0c;也定义了自己的语法和词汇。学习C语言&#xff0c;首先要学习C语言的词汇&#xff0c;再学习C语言的语法规则&#xff0c;然后由词汇构成语句&#xff0c;由语句构成源程…

c语言中ftell函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、C语言函数ftell用于获取文件位置指针当前位置相对于文件首的偏移字节数。2、通过ftell函数获取当前文件的大小&#xff0c;然后通过fread函数读取缓冲区。返回值&#xff0c;如果成功&#xff0c;该函数返回位置标识符的当前值&a…

jdk入门_JDK 9 REPL:入门

jdk入门会议是聚会Java名人的好地方。 Devoxx France是与Java语言架构师&#xff0c;前同事和老朋友Brian Goetz&#xff08; briangoetz &#xff09;见面的一个机会。 我们谈论了JDK 9&#xff0c;而他全都热衷于REPL。 他提到&#xff0c;尽管Java SE 9中有很多重要功能 &am…

c语言中局部变量是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、函数内部定义的变量称为局部变量&#xff0c;其作用域仅限于函数内部&#xff0c;离开函数后无效&#xff0c;使用后报错。2、局部变量只能在函数内部使用&#xff0c;离开函数后无效&#xff0c;再次使用会报错。实例#include &…

java接口自动化Excel占位符_基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport的接口自动化测试框架...

接口自动化框架项目说明本框架是一套基于mavenjavaTestNGhttpclientpoijsonpathExtentReport而设计的数据驱动接口自动化测试框架&#xff0c;TestNG 作为执行器&#xff0c;poi用于读取存放于excel的接口用例&#xff0c;jsonPath用于校验返回值&#xff0c;以及提取返回值。本…

C语言为什么要定义short,int,long这么多整数类型?

点击上方蓝字关注我&#xff0c;了解更多咨询整数类型有int、short int、long int三种类型&#xff0c;用于需要不同存储空间的整数使用。整数类型有正整数和负整数之分&#xff0c;在C语言中&#xff0c;规定整型的最高位为符号位&#xff0c;最高位为“0”表示正数&#xff0…

c语言中函数参数类型的探究

点击上方蓝字关注我&#xff0c;了解更多咨询函数中的参数个数可以是0&#xff0c;也可以是一个或多个参数。下面我们带着这三种不同的情况&#xff0c;分别在c语言中进行讨论。1、函数没有参数&#xff0c;表示没有参数列表。int func1(); //声明一个函数&#xff0c;该函数…

c语言野指针产生的原因

点击上方蓝字关注我&#xff0c;了解更多咨询1、指针变量未初始化&#xff0c;任何指针变量刚被创建时不会自动成为 NULL 指针&#xff0c;它的缺省值是随机的。所以&#xff0c;指针变量在创建的同时应当被初始化&#xff0c;要么将指针设置为 NULL &#xff0c;要么让它指向合…

c语言中assert函数的使用注意

点击上方蓝字关注我&#xff0c;了解更多咨询1、使用assert检查函数开始时传入参数的合法性。2、每个assert只检验一个条件&#xff0c;因为在同时检验多个条件时&#xff0c;如果断言失败&#xff0c;就无法直观地判断哪个条件失败。实例int resetBufferSize(int nNewSize) {/…

es 调整gc_实际中进行GC调整

es 调整gc调优垃圾回收与任何其他性能调优活动没有什么不同。 您需要确保您了解当前的情况和所需的结果&#xff0c;而不是因为对应用程序的随机部分进行调整而产生了诱惑。 通常&#xff0c;只需执行以下过程即可&#xff1a; 陈述您的绩效目标 运行测试 测量 与目标比较…

c语言中assert函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、assert将通过检查表达式expresion的值来决定是否需要终止执行程序。2、如果表达式expresion的值是假的(即0)&#xff0c;它将首先向标准错误流stderr打印错误信息。通过调用abort函数终止程序运行。否则&#xff0c;assert没有效…

sci检索没有馆藏号_转变馆藏

sci检索没有馆藏号您是否曾经想替换过HashSet或HashMap使用的equals和hashCode方法&#xff1f; 或者有一个List的一些元素类型伪装成的List相关类型的&#xff1f; 转换集合使这成为可能&#xff0c;并且本文将展示如何实现。 总览 转换集合是LibFX 0.3.0的一项功能&#xf…

c语言中exit和return的区别

点击上方蓝字关注我&#xff0c;了解更多咨询1、返回函数值的return是关键字&#xff0c;exit是一个函数。return是语言级的&#xff0c;它表示调用堆栈的返回&#xff1b;exit是系统调用级的&#xff0c;它表示一个过程的结束。2、return是函数的退出&#xff0c;exit是进程的…

java怎样返回json_java怎么返回json

详细内容本篇文章将介绍如何编写Java程序来返回Json数据&#xff0c;本次以三个方式进行介绍。推荐课程&#xff1a;Java教程&#xff0c;方式1&#xff1a;当然是手敲所有代码&#xff0c;来进行json数据的返回。需要 HttpHttpServletRequest request HttpServletResponse res…

c语言中realloc函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、判断当前指针是否有足够的连续空间。如果足够&#xff0c;扩大ptr指向的地址并返回。如果不够&#xff0c;如何根据size指定的大小分配空间&#xff0c;将原始数据复制到新分配的内存中&#xff0c;然后释放原始ptr指向的区域。2…

java jsp学习指南_JSP教程–最终指南

java jsp学习指南编者注&#xff1a; JavaServer Pages&#xff08;JSP&#xff09;技术使您可以轻松创建同时包含静态和动态组件的Web内容。 JSP技术提供了Java Servlet技术的所有动态功能&#xff0c;但提供了一种更自然的方法来创建静态内容。 JSP技术的主要功能包括用于开…

c语言中main函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、main函数是C程序的入口函数&#xff0c;即程序的执行从main函数开始&#xff0c;其他函数的调动也直接或间接地在main函数中调用。2、main函数的返回值用于解释程序的退出状态。若返回0&#xff0c;则表示程序正常退出。返回其他…

c语言中__cplusplus是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、__cplusplus和extern“C”一般都是配对使用&#xff0c;如果定义了__cplusplus(cpp文件默认定义了该宏)&#xff0c;则采用C语言方式进行编译。2、是在C中特有的&#xff0c;__cplusplus 其实就是C。实例#ifndef __CODERSRC_H__ …

c语言中fwirte函数的使用方法示例

点击上方蓝字关注我&#xff0c;了解更多咨询1、fwrite函数用于将缓冲区数据写入文件&#xff0c;并返回成功写入文件的元素数。如果出现错误或到达文件末尾&#xff0c;可能小于nmemb。2、fwrite函数不区分文件的尾部和错误&#xff0c;因此调用者必须使用feof和ferror来判断发…