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

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

乍一看,垃圾收集应该处理顾名思义的问题–查找并丢弃垃圾。 实际上,它所做的恰恰相反。 垃圾收集正在跟踪所有仍在使用的对象,并将其余对象标记为垃圾。 牢记这一点,我们开始深入研究如何为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)都采用这种方法。 最好用图片来说明:

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

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

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

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

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

扫一扫

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

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

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

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

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

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

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

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

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

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

垃圾回收算法以及垃圾回收器_什么是垃圾回收?相关推荐

  1. JVM垃圾回收算法及垃圾回收器

    目录 一.垃圾回收GC (Garbage Collection) 1.1 垃圾回收介绍: 1.2  如何判断对象是否存活(被使用) 1.2.1 引用计数算法(已经废弃) 1.2.2 可达性分析 二.垃 ...

  2. 图解JVM垃圾回收算法

    1 简单介绍下----->垃圾回收概念 GC中的垃圾,指的是存在于内存中的.不会再被使用的对象.而垃圾回收就是把那些不再被使用的对象进行清除,收回占用的内存空间.如果不及时对内存中的垃圾进行清理 ...

  3. JVM之垃圾回收算法详解

    JVM之垃圾回收算法详解 现有的垃圾回收算法 分类 垃圾收集器的设计原则 标记-清除算法 缺点 标记-复制算法 "Apple回收策略" 缺点 标记-整理算法 缺点 总结 现有的垃圾 ...

  4. 垃圾回收概述(垃圾回收算法)

    垃圾回收概述 Java 和 C++语言的区别,就在于垃圾收集技术和内存动态分配上,C++语言没有垃圾收集技术,需要程序员手动的收集. 垃圾收集,不是Java语言的伴生产物.早在1960年,第一门开始使 ...

  5. 【JVM从小白学成大佬】4.Java虚拟机何谓垃圾及垃圾回收算法

    在Java中内存是由虚拟机自动管理的,虚拟机在内存中划出一片区域,作为满足程序内存分配请求的空间.内存的创建仍然是由程序猿来显示指定的,但是对象的释放却对程序猿是透明的.就是解放了程序猿手动回收内存的 ...

  6. 垃圾回收算法——标记—清扫回收算法

    理想的垃圾回收的目的是回收程序不再使用的对象所占用的空间,任何自动内存管理系统都面临三个任务: 为对象分配空间: 确定存活对象: 回收死亡对象所占用的空间: 这些任务并非相互独立,特别是回收空间的方法 ...

  7. 【Android 内存优化】内存抖动 ( 垃圾回收算法总结 | 分代收集算法补充 | 内存抖动排查 | 内存抖动操作 | 集合选择 )

    文章目录 一. 垃圾回收算法总结 二. 分代收集算法补充 三. 查看 Java 虚拟机 四. 获取 Android 应用可使用最大内存 五. 内存抖动标志 六. 排查内存抖动 七. 常见的造成内存抖动 ...

  8. java+垃圾回收器+的功能_JAVA-JVM 垃圾回收器

    分代收集:新生代(复制算法),老年代(标记清除,标记整理) . jps -v 可查看当前JVM 使用的是那种垃圾收集器 垃圾回收器又分单线程多线程,使用. 常见的垃圾回收器如下图:垃圾回收器的连线表示 ...

  9. java 内存回收参数_JAVA虚拟机内存回收算法与调优参数

    一.相关概念 基本回收算法 引用计数(Reference Counting)比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象. ...

最新文章

  1. python写表格_使用Python对Excel进行读写操作
  2. 安装VMware并新建虚拟机
  3. Hadoop HDFS (3) JAVA訪问HDFS之二 文件分布式读写策略
  4. SpringMVC快速入门-开发步骤
  5. Errors were encountered while processing 解决方法
  6. 自定义MongoDB的Spring Social Connect框架
  7. python自制有声小说
  8. 为什么要学Win32及Win32程序框架
  9. Java Web学习笔记08:分页技术
  10. log4j日志输出配置
  11. 超级人工智能何时能实现?
  12. idea隐藏菜单栏Main Menu 恢复方法
  13. Kotlin by lazy解析及在findviewById场景中的使用
  14. 2021-2025年中国服装合同制造的物流行业市场供需与战略研究报告
  15. 棣拓DTAS公差分析软件-蒙特卡洛法公差分析软件-容差分析软件
  16. model.train()与model.eval()的用法、Dropout原理、relu,sigmiod,tanh激活函数、nn.Linear浅析
  17. 在英语课堂中培养学生音素觉知的初步探讨(Phonemic Awareness)
  18. Linux安装Siege
  19. 【ubuntu】搭建lamp架构
  20. 浅析Trafodion体系结构

热门文章

  1. CF1375F-Integer Game【交互】
  2. YbtOJ#573-后缀表达【二分图匹配】
  3. P2371-[国家集训队]墨墨的等式【同余最短路】
  4. P3808,P3796-[模板]AC自动机(简单版/加强版)
  5. P2698-花盆Flowerpot【单调队列】
  6. 【jzoj】2018.1.30NOIP普及组——模拟赛D组
  7. 操作系统复习笔记 05 Thread 线程
  8. 5、play中的json数据处理
  9. Spring经典面试题和答案
  10. 为什么我强烈建议大家使用枚举来实现单例