Java的内置垃圾收集如何使您的生活更美好(大部分时间)

通过从应用程序中学习企业APM产品,发现更快,更高效的性能监控。 参加AppDynamics APM导览!

“无需为用户编写将寄存器返回到自由存储列表的程序。”

该行(以及随后的十几行)被埋在约翰·麦卡锡(John McCarthy)具有里程碑意义的论文中 ,该论文发表于1960年,“符号表达式的递归函数及其由机器进行的计算”。这是对自动内存的第一个已知描述。管理。

在指定如何在Lisp中管理内存时,McCarthy能够排除显式的内存管理。 因此,麦卡锡(McCarthy)减轻了开发人员对手动内存管理的烦恼。 使这个故事真正令人惊奇的是,这几个词激发了其他人将某种形式的自动内存管理(也称为垃圾收集 (GC))整合到此后开发的四分之三的更广泛使用的语言和运行时中。 该列表包括两个最受欢迎的平台,即Java的虚拟机 (JVM)和.NET的公共语言运行时 (CLR),以及Google即将推出的Go Lang 。 GC不仅存在于大型企业中,还存在于移动平台上,例如Android的Dalvik,Android Runtime和Apple的Swift。 您甚至可以在Web浏览器以及SSD等硬件设备上找到运行的GC。 让我们探讨一些为什么行业更喜欢自动化而不是手动内存管理的原因。

自动内存管理的开端

那么,麦卡锡如何设计自动内存管理? 首先,Lisp引擎将Lisp表达式分解为子表达式,每个S表达式都存储在链接列表中的单个单词节点中。 节点是从空闲列表中分配的,但是在将其清空之前,不必将它们返回到空闲列表。

一旦空闲列表为空,运行时就会跟踪链接列表并标记所有可到达的节点。 接下来,它扫描包含所有节点的缓冲区,并将未标记的节点返回到空闲列表。 重新填写自由列表后,应用程序将继续。

今天,这被称为单空间,就地跟踪垃圾收集。 该实现非常初级:它只需要处理一个非循环定向图,其中所有节点的大小都完全相同。 仅运行一个线程,并且该线程执行了应用程序代码或垃圾回收器。 相反,当今JVM中的收集器必须处理有向图,其循环和节点的大小不一致。 JVM是多线程的,可在多核CPU(可能是多插槽的主板)上运行。 因此,今天的实现要复杂得多,以至于GC专家很难预测任何给定情况下的性能。

行动缓慢:垃圾回收暂停时间

当Lisp垃圾收集器运行时,应用程序停止了。 在Lisp的初始版本中,收集器通常占用30%到40%的CPU周期。 在1960年代的硬件上,这可能导致应用程序停顿几分钟,这被称为“世界停止” 。 好处是分配几乎对应用程序吞吐量(完成的有用工作量)没有任何影响。 此实现突出显示了暂停时间和对应用程序吞吐量的影响之间的持续斗争,这一斗争一直持续到今天。

通常,收集器的暂停时间特性越好,它对应用程序吞吐量的影响就越大。 Java当前的实现都带有暂停时间/开销成本。 并行收集具有较长的暂停时间和较低的开销,而大多数并发的收集器具有较短的暂停时间并消耗更多的计算资源(包括内存和CPU)。

任何GC实现者的目标都是最大程度地保证保证变种线程能够接收的最少处理器时间,这一概念称为最小变种利用率(MMU)。 即使这样,当前的GC开销也可以很好地运行在5%以下,而在典型的C ++应用程序中您将遇到15%到20%的开销。

那么,为什么不像在Java应用程序中那样感到这种开销呢? 由于开销在C / C ++运行时间中平均分配,因此最终用户看不到它。 实际上,有关托管内存的最大抱怨是,它在无法预测的时间内暂停了您的应用程序不可预测的时间。

垃圾收集进展

Sun Java最初的垃圾收集器并没有改善垃圾收集的形象。 它的单线程,单行距实现使应用程序停滞了很长时间,极大地拖累了分配率。 直到Java 2才引入了代内存池方案(以及并行的(主要是并发的和增量的)收集器)。 尽管这些收集器提供了改进的暂停时间特性,但是暂停时间仍然是个问题。 而且,这些实现非常复杂,以致大多数开发人员不太可能具有调整它们的必要经验。 为了使情况更加复杂,IBM,Azul和RedHat拥有一个或多个自己的垃圾收集器-每个垃圾收集器都有自己的历史,优势和怪癖。 此外,包括SAP,Twitter,Google,阿里巴巴在内的许多公司都拥有自己的内部JVM团队,并带有Garbage收集器的修改版本。

随着时间的流逝,增加了备用且更复杂的分配路径导致分配开销图的巨大改进。 例如,JVM中的快速路径分配现在比C / C ++中的典型分配快大约30倍。 麻烦之处在于:只有可以通过转义分析测试的数据才有资格进行快速路径分配。 (幸运的是,我们的绝大多数数据都通过了此测试,并从此备用分配路径中受益。)

另一个优点是撤离收集器带来的成本降低和成本模型简化。 在这种方案中,收集器将实时数据复制到另一个内存池。 因此,不存在恢复短命数据的成本。 这并不是分配广告恶心的邀请,因为每次分配都会产生成本,并且高分配率会触发更频繁的GC活动并累积额外的复制成本。 抽空收集器有助于提高GC的效率和可预测性,但仍然存在大量资源成本。

那导致我们记忆。 内存管理要求您保留的内存至少是手动内存管理需要的五倍。 有时开发人员肯定会释放数据。 在这些情况下,显式释放而不是通过决策使收集者有理由便宜。 正是这些成本使苹果最初选择了Objective-C的手动内存管理。 在Swift中,Apple选择使用引用计数。 他们为弱引用和自有引用添加了注释,以帮助收集器应对循环引用。

还有其他无形的或难以衡量的成本可以归因于运行时的设计决策。 例如,失去对内存布局的控制权可能导致应用程序性能受L2高速缓存未命中和高速缓存行密度的支配。 在这些情况下,性能下降很容易超过10:1。 未来实现者面临的挑战之一是如何更好地控制内存布局。

回顾一下当第一次将Lisp引入Lisp时GC的性能如何,以及通向其当前状态的漫长而又令人沮丧的道路,很难想象为什么任何构建运行时的人都想使用托管内存。 但是请考虑一下,如果您手动管理内存,则需要访问底层的参考系统-这意味着该语言需要添加语法来操作内存指针。

依靠托管内存的语言始终缺乏管理指针所需的语法,因为保证了内存一致性。 这保证了所有指针都将指向它们应指向的位置,而如果您碰巧踩了它们,则无需悬空(空)指针等待耗尽运行时间。 如果允许开发人员直接创建和操作指针,则运行时无法保证。 另外,将其从语言中删除会消除间接性,这是开发人员更难掌握的概念之一。 漏洞常常是由于从事精神体操的开发人员需要处理许多竞争问题并弄错而造成的。 如果这种混合包含通过应用程序逻辑进行推理,以及手动内存管理和不同的内存访问模式,则错误可能会出现在代码中。 实际上,依赖手动内存管理的系统中的错误是当今系统中最严重和最大的安全漏洞来源之一。

为了防止这些类型的错误,开发人员总是要问:“我是否仍然有可行的参考资料来阻止我释放这些资料?” 这个问题的答案通常是“我不知道”。 如果对该数据的引用被传递到系统中的另一个组件,则几乎不可能知道是否可以安全地释放内存。 众所周知,指针错误会导致数据损坏,或者在最佳情况下会导致SIGSEGV。

从图片中删除指针往往会产生一个更具可读性,更易于推理和维护的代码。 GC知道何时可以回收内存。 此属性使项目可以安全地使用第三方组件,这在使用手动内存管理的语言中很少发生。

结论

在最佳状态下,内存管理可谓是一项繁琐的簿记任务。 如果可以将内存管理排除在待办事项之外,那么开发人员往往会提高工作效率,并产生更少的错误。 我们还已经看到,GC并不是万能药,因为它有自己的一系列问题。 但是幸运的是,向更好的实现迈进的步伐还在继续。

Go Lang的新收集器结合了引用计数和跟踪功能,以减少开销并最大程度地减少暂停时间。 Azul声称已通过大大降低暂停时间来解决GC暂停问题。 Oracle和IBM一直在致力于收集器,他们认为收集器更适合包含大量数据的超大堆。 RedHat已与Shenandoah展开竞争,Shenandoah的目标是从运行时间中完全消除暂停时间。 同时,Twitter和Google继续改善现有的收藏家,因此它们继续对新的收藏家具有竞争力。

通过从应用程序中学习企业APM产品,发现更快,更高效的性能监控。 参加AppDynamics APM导览!

翻译自: https://www.javacodegeeks.com/2017/02/javas-built-garbage-collection-will-make-life-better-time.html

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

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

相关文章

PyOpenCV 坐标系统

pyOpenCV中的坐标系统,以图片左上角为原点(0,0),水平方向为x轴(也既图像的宽度width),竖直方向为y轴(也既图像的高度height),如下图所示: #图像中…

office 论文 页码_毕业论文必备技巧:Word页码从第三页开始设置方法

许多应届毕业生在排版毕业论文时候,都会按要求设置页码,第一页是封面,第二页是目录,那么正文内容就要从第三页正式开始了。按照正规设置方式,那么页码此时应该是第三页。但是按照论文格式规定,页码应该是从…

散列

一.什么是散列 散列使用一个散列函数,将一个键映射到一个索引上。散列非常高效。使用散列将耗费O(1)时间来查找、插入、及删除一个元素。 映射表是一种用散列实现的数据结构,映射表是一种存储条目的容器,每个条目包含两个部分:一个…

移动端触摸(touch)事件

目有个交互需要实现手指滑动的交互,pc端使用mousedown,mousemove,mouseup监听实现。 但在ios设备上mousemove是不好监听的,同类的方法是touchstart,touchmove,touchend。 项目需求,需要用到拖动事件。由于不需要考虑IE8等低端浏览器的兼容性&…

numcpp速度对比_PHP和C++性能对比.pdf

PHP 与C性能比较本文博客链接:http://keping.me/php_vs_cpp/PHP 是速度很快的脚本语言,但是用了框架以后好像感觉挺慢的。于是猜测会不会PHP 本身也不是很快。如果不是很快,能否采用 PHP 调用本地动态链接库的形式来提升速度。于是有了下面的…

jndi ldap_什么是JNDI,SPI,CCI,LDAP和JCA?

jndi ldapJNDI代表Java命名和目录接口 。 它是用于提供对目录服务(即,服务映射名称(字符串)与对象,对远程对象或简单数据的引用)访问的API。 这就是所谓的 约束力 。 绑定集称为上下文 。 应用程序使用JND…

PyOpenCV 基本操作

目录 1. 图片加载、显示和保存 2. 图像显示窗口创建与销毁 3. 图片宽、高、通道数获取 4. 图像像素数目和图像数据类型的获取 5. 生成指定大小的空图像, 生成指定大小的空图像 6. 访问和操作图像像素 7. 图像三通道分离和合并 8. 抓取摄像头 1. 图片加载、显示和保存 …

python中用于标识字符串的定界符_Python 基本数据类型

######################基本数据类型######################数字类型整数 int整数是用来表示整数数值,即没有小数部分的数值,包括正整数 负整数和0整数类型包括十进制整数 八进制整数 十六进制整数和二进制整数例如: 0 , 100 , 65205浮点数 float浮点数由整数部分和小数部分组成…

适用于Java开发人员的Elasticsearch:命令行中的Elasticsearch

本文是我们学院课程的一部分,该课程的标题为Java开发人员的Elasticsearch教程 。 在本课程中,我们提供了一系列教程,以便您可以开发自己的基于Elasticsearch的应用程序。 我们涵盖了从安装和操作到Java API集成和报告的广泛主题。 通过我们简…

系统间账号认证系统同步方案

系统间账号认证系统同步方案 基础原理:(基于Web) 浏览器在个请求传递cookie到服务器,服务器对cookie增删改查的操作, 写入JSessionId实现与服务器Session的绑定,保持会话 单机情况下:一个域名,对应一个cookie&#xff…

Pytorch 加载预训练模型参数时出现size mismatch错误

目录 1 不妨先研究一下’ resnet18-5c106cde.pth’里面存了什么东西以及它的数据类型 (1_1)’ resnet18-5c106cde.pth’的数据类型

python元类单例_python面向对象和元类的理解

1 python类对象与实例对象python中一切皆对象(广义上的对象),类也不例外,我们可以称类为类对象。python中内建函数type()可以返回对象的类型,例如type(int)会得到返回值,而int为类型工厂函数,是内置的类对象。如果对自…

Java命令行界面(第7部分):JCommander

这是我系列的第七篇文章,简要介绍了用于处理Java命令行参数的各种库。 这篇文章回到了基于注释的库的覆盖范围,该库似乎是在Java中可用于处理命令行参数的众多可用库中知名度最高和最受欢迎的库之一: JCommander 。 JCommander的网页上指出&…

Pytorch 加载部分预训练模型并冻结某些层

目录 1 pytorch的版本&#xff1a; 2 数据下载地址&#xff1a; 3 原始版本代码下载&#xff1a; 4 直接上代码&#xff1a; 1 pytorch的版本&#xff1a; 2 数据下载地址&#xff1a; <https://download.pytorch.org/tutorial/hymenoptera_data.zip> 3 原始…

INT类型知多少

前言&#xff1a; 整型是MySQL中最常用的字段类型之一&#xff0c;通常用于存储整数&#xff0c;其中int是整型中最常用的&#xff0c;对于int类型你是否真正了解呢&#xff1f;本文会带你熟悉int类型相关知识&#xff0c;也会介绍其他整型字段的使用。 1.整型分类及存储范围 整…

altera fpga 型号说明_A/X家FPGA架构及资源评估

欢迎FPGA工程师加入官方微信技术群点击蓝字关注我们FPGA之家-中国最好最大的FPGA纯工程师社群评估对比xilinx以及altera两家FPGA芯片逻辑资源。首先要说明&#xff0c;现今FPGA除了常规逻辑资源&#xff0c;还具有很多其他片内资源比如块RAM、DSP单元、高速串行收发器、PLL、AD…

guava api_使用Google Guava的订购API

guava api我们在Google的Guava库中玩的更多&#xff0c;这真是一个了不起的库&#xff01; 我们用于它的最新内容是为我们的域对象整理比较器。 这是如何做。 使用Apache Isis的JDO Objectstore &#xff0c;使您的类实现java.lang.Comparable &#xff0c;并对集合使用SortedS…

Pytorch 加载和保存模型

目录 保存和加载模型 1. 什么是状态字典&#xff1a;state_dict? 2.保存和加载推理模型 2.1 保存/加载 state_dict &#xff08;推荐使用&#xff09; 2.2 保存/加载完整模型 3. 保存和加载 Checkpoint 用于推理/继续训练 4. 在一个文件中保存多个模型 5. 使用在不同…

02-CSS基础与进阶-day9_2018-09-12-20-29-40

定位 静态定位 position: static 相对定位 position: relative 绝对定位 position: absolute 脱标 参考点 子绝父相 让绝对定位的盒子水平居中和垂直居中 固定定位 position: fixed 参考点 浏览器左上角 固定定位的元素脱标不占有位置 兼容性 ie6低版本不支持固定定位 02绝对…

activity直接销毁_Android -- Activity的销毁和重建

两种销毁第一种是正常的销毁&#xff0c;比如用户按下Back按钮或者是activity自己调用了finish()方法&#xff1b;另一种是由于activity处于stopped状态&#xff0c;并且它长期未被使用&#xff0c;或者前台的activity需要更多的资源&#xff0c;这些情况下系统就会关闭后台的进…