垃圾收集算法,垃圾收集器_弱,弱,最弱,利用专家参考来管理垃圾收集器

垃圾收集算法,垃圾收集器

何时以及何时不使用Java中的专家引用

弱引用,软引用和幻像引用既危险又强大。 如果以错误的方式使用它们,则会破坏JVM性能。 但是,如果使用正确的方法,它们可以大大提高性能和程序清晰度。

弱引用和软引用在这三种中更为明显。 实际上,它们几乎是同一件事! 这个想法很简单,就是将它们用于访问对象,但不会阻止垃圾回收器回收该对象:

Object y=new Object();
// y is a hard reference to the object
// and so that object cannot be reclaimed.Obejct x=WeakReference<Object>(y);
// now x is a weak reference to the object
// (not to y - as y is just a variable).
// The object still cannot be reclaimed 
// because y is still a hard reference to it.y=null;
// now there is only a weak reference to 
//the object, it is eligible for garbage collection.if(x.get()==null){System.out.println("The object has gone away");
}else{System.out.println("The object is " + x.get().toString());
}

您发现故意的错误吗? 这是一个容易错过的东西,并且可能不会在单元测试中显示。 这正是让我说的问题:

仅在绝对必要且可能甚至没有的情况下,才使用弱/软引用。

当JVM承受内存压力时,它可能会在弱引用中的get方法的第一次和第二次调用之间回收该对象。 当在null上调用toString方法时,这将导致程序引发null指针异常。 该代码的正确形式为:

Object x=x.get();
// Now we have null xor a hard reference to
// the object
if(z==null){System.out.println("The object has gone away");
}else{System.out.println("The object is " + z.toString());
}

我们为什么要他们?

我们还没有完全谈到为什么它们真的非常危险。 为此,我们需要了解为什么我们可能需要它们以及为什么我们需要它们。 在两种常见的情况下,弱引用和软引用似乎是个好主意(我们将在稍后介绍软和弱引用之间的区别)。 首先是某种形式的RAM缓存。

它是这样的:

我们有一些数据,例如客户详细信息,存储在数据库中。 我们一直在寻找它,这很慢。 我们可以做的是将这些数据缓存在RAM中。 但是,最终RAM将填充名称和地址,并且JVM抛出OutOfMemoryError。 解决方案是将名称和地址存储在只能弱访问的对象中。 像这样:

ConcurrentHasMap>String,WeakReference>CustomerInfo<< cache=new ConcurrentHashMap><();
...
CustomerInfo currentCustomer=cache.get(customerName);
if(currentCustomer==null){currentCustomer=reloadCachesEntry(customerName);
}

这种无害的小模式非常有能力使巨型的JVM崩溃。 该模式使用JVM的垃圾回收器来管理内存中的缓存。 垃圾收集器从未被设计为这样做。 该模式通过用难以到达的对象填充内存来滥用垃圾收集器,这些对象使JVM耗尽了堆空间。 当JVM的内存不足时,它必须遍历其堆中的所有引用(弱引用,软引用和其他引用)并回收RAM。 这是昂贵的并且显示为处理成本。 在具有许多处理器核心的超大型JVM实例上,情况甚至更糟,因为垃圾收集器很可能最终不得不执行“停止世界”的完整循环,从而将性能降低到单核级别!

我并不是说内存缓存技术不是一个好主意。 哦,不,这是个好主意。 但是,仅将其扔到垃圾收集器上并且不期望麻烦是一种非常糟糕的设计选择。

弱vs软

有什么区别? 好吧,真的有很多。 在某些JVM(例如,客户端托管JVM的客户端,但可能随时更改)上,弱引用被标记为优先垃圾收集。 换句话说,与其他内存相比,垃圾回收器应更努力地从它们引用的对象图中回收内存(并且不引用软或硬引用)。 软引用对他们没有这个想法。 但是,这只是某些JVM上的可选概念,不能被依赖,而且还是一个坏主意。 我建议始终使用软引用或弱引用,并坚持使用它。 选择您喜欢的声音。 我更喜欢WeakReference这个名字,所以倾向于使用它。

还有一个区别。 被软引用弱引用而不是硬引用引用的对象可能会遇到这样的情况,即仍然可以从弱引用的.get()方法中获取,而不能从软引用的.get()方法中获取。 反之亦然,反之亦然。 依赖于此行为的代码可能是错误的标题。

弱引用的良好用法

确实存在。 弱引用对跟踪其他地方正在使用的对象很有用。 一个示例来自Sonic Field(音频处理程序包)。 在此示例中,文件中的“插槽”包含音频数据,并与内存中的对象相关联。 该模型不使用弱引用来引用数据的内存中副本。 在内存对象中使用插槽。 弱引用用于允许文件管理系统重用插槽。

使用插槽的代码不需要(也不应该)与磁盘空间的管理有关。 文件管理器很关心这样做。 文件管理器对使用插槽的对象有较弱的引用。 当请求一个新的插槽时,文件管理器将检查通过弱引用引用的所有现有插槽,这些弱引用已被回收(因此从get方法返回null)。 如果找到这样的引用,则可以重用该插槽。

自动通知回收

有时,我们可能想知道何时回收了弱引用或软引用(或其他类型的幻像)。 这可以通过排队系统来完成。 我们可以使用参考队列来做到这一点:

WeakReference(T referent, ReferenceQueue<? super T> q)

我们做这样的事情:

ReferenceQueue junkQ = new ReferenceQueue<>();
....
WeakReference<FileSlot> mySlot=new WeakReference<>(aSlot);
....
// In a different thread - make sure it is daemon!
WeakReference<FileSlot> isDead;
while(true){isDead = junkQ.remove();// Take some action based on the fact it is dead// But - it might not be dead - see end of post :(
...
}

但是,请记住,当弱引用在junkQ上结束时,对其调用.get()将返回null。 如果您必须存储信息以允许您感兴趣的任何操作发生在其他地方(例如,ConcurrentHashMap,其中引用是关键),

那么什么是幻影引用?

虚拟引用是一种,当您需要它们时,您确实需要它们。 但是从表面上看,它们似乎毫无用处。 您会看到,每当在幻像引用上调用.get()时,总会返回null。 永远不可能使用幻像引用来引用它所引用的对象。 好吧-这不是真的。 有时我们可以通过JNI来实现这一目标,但我们绝对不应该这样做。

考虑一下您在与Java对象关联的JNI中分配本机内存的情况。 这是JDK的noi包中的DirectBuffers使用的模型。 这是我在大型商业项目中反复使用的东西。

那么,我们如何回收本机内存呢?

对于类似文件的系统,可以说在关闭文件之前不会回收内存。 这将资源管理的责任放在程序员的肩膀上; 这正是程序员对文件之类的期望。 但是,对于重量较轻的对象,我们的程序员不喜欢考虑资源管理-垃圾收集器可以为我们做这件事。

我们可以将代码放在终结器中,终结器调用JNI代码来回收内存。 这是很糟糕的(就像致命的一样),因为JVM几乎可以保证它们将调用终结器。 所以,不要那样做! 但是,幻象引用可以解救! 首先,我们需要理解“幻影可到达”:只有当幻象引用无法通过其他任何类型的引用(硬,弱或软)到达时,它才会被排队。 在这一点上,幻影参考可以入队。 如果对象具有终结器,则它将被忽略或运行。 但它不会“将物体带回生活”。 幻影可到达对象对于JNI本机代码(或任何其他代码)来说是“安全的”,可以根据资源回收资源。

因此,带有幻像引用的代码如下所示:

ReferenceQueue<FileSlot> junkQ = new ReferenceQueue<>();
....
Phantom<FileSlot> mySlot=new Phantom<>(aSlot);
....
// In a different thread - make sure it is daemon!
Phantom<FileSlot> isDead;
while(true){isDead=junkQ.remove();long handle=lookUpHandle(isDead);cleanNativeMemory(handle);
}

在这种模式下,我们保留了一个句柄,本机代码可使用该句柄在Java中的结构(可能是另一个哈希图)中查找和回收资源。 当我们完全确定Java对象无法重生时-它是幻影可到达的(即幽灵-我们可以安全地回收本机资源。如果您的代码使用sun.misc.unsafe进行了其他“顽皮的”事情(对于有关使用此技术的完整示例,请参见这篇文章 。

关于幻影引用的最后思考。 从技术上讲,可以使用弱引用来实现与上述相同的模式。 但是,这并不是弱引用的目的,并且这种模式会滥用它们。 幻象引用绝对保证对象确实已死,因此可以回收资源。 仅举一个例子,从理论上讲,可以将弱引用加入队列,然后由其终结器将对象恢复原状,因为终结队列的运行速度比弱参考队列慢。 这种幻影恐怖故事不可能在幻影引用中发生。

有一个小问题,这是JVM设计的弱点。 也就是说,JNI全局弱引用类型与幻像引用具有未定义的关系。 有人建议即使将对象排队为幻像引用,也可以使用全局弱引用来获取对象。 这是对JVM的一种特定实现的怪癖,永远不要使用。

参考: 弱,更弱,最弱,利用垃圾收集器 ,以及来自Java日历日历博客上我们JCG合作伙伴 Alexander Turner的专业参考 。

翻译自: https://www.javacodegeeks.com/2012/12/weak-weaker-weakest-harnessing-the-garbage-collector-with-specialist-references.html

垃圾收集算法,垃圾收集器

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

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

相关文章

ESP8266—“ICACHE_FLASH_ATTR”宏

问&#xff1a;ESP8266_NONOS_SDK中ICACHE_FLASH_ATTR宏的用途是什么&#xff1f;我看到它取决于ICACHE_FLASH&#xff0c;但我不知道何时应该定义该符号。什么时候需要包括它&#xff1f;答&#xff1a;对于ESP8266_NONOS_SDK&#xff0c;用ICACHE_FLASH_ATTR编译的函数编译到…

layui网页html编辑器,layui使用富文本编辑器

HTML代码&#xff1a;这里的原理是你输入的内容会经过处理插入到文本区域textarea中js代码&#xff1a;/*** 文本编辑器*/layui.use([form, layedit], function(){var layedit layui.layedit;//上传图片,必须放在 创建一个编辑器前面layedit.set({uploadImage: {url: upload /…

Java应用程序性能监视:复杂的分布式应用程序的端到端性能

通过从应用程序中学习企业APM产品&#xff0c;发现更快&#xff0c;更高效的性能监控。 参加AppDynamics APM导览&#xff01; 在最复杂和分布式环境中端到端监视Java应用程序性能-专注于业务事务。 自动发现的业务交易&#xff0c;动态基准&#xff0c;代码级诊断和虚拟作战室…

C#设计模式(2)——简单工厂模式

一、引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式——简单工厂模式。 二、简单工厂模式的介绍 说到简单工厂&#xff0c;自然的第一个疑问当然就是什…

计算机应用基础课程基本要求,计算机应用基础课程标准

《计算机应用基础》课程标准一、课程性质&#xff1a;《计算机应用基础》课程是中职学校各专业学生必修的一门公共基础课程&#xff0c;具有很强的实践性和应用性&#xff0c;是各行各业从事现代化办公、计算机设计及应用等领域人材所必须具备的理论知识和实践技能。通过本课程…

S3C2410 bootloader ----VIVI阅读笔记 (转)下

1 static inline void mem_mapping_linear(void) 2 { 3 unsigned long pageoffset, sectionNumber; 4 putstr_hex("MMU table base address 0x", (unsigned long) mmu_tlb_base); 5 /* 4G 虚拟地址映射到相同的物理地址. not cacacheable, no…

华南理工网络计算机基础知识,2019年华南理工大学网络教育计算机基础随堂练习题第一章.docx...

计算机基础知识第一节 计算机的基本概念随堂练习提交截止时间&#xff1a;2019-06-15 23:59:59本次练习有题&#xff0c;你已做题&#xff0c;已提交题&#xff0c;其中答对题。当前页有6题&#xff0c;你已做6题&#xff0c;已提交6题&#xff0c;其中答对6题。1.(单选题)? 计…

orm jdbc_Spring Data JDBC通用DAO实现–迄今为止最轻量的ORM

orm jdbc我很高兴宣布Spring Data JDBC存储库项目的第一个版本。 这个开源库的目的是为基于Spring框架中 JdbcTemplate关系数据库提供通用&#xff0c;轻量且易于使用的DAO实现&#xff0c;与项目的Spring Data 框架兼容。 设计目标 轻巧&#xff0c;快速且开销低。 只有少数几…

NOIP模拟测试9「随·单·题」

liu_runda出的题&#xff0c;先$\%\%\%\%\%\%\%\%\%\%\%$为敬 随 考试时没有Qj 然后甚至没做,甚至没交 我不知道我怎么想的 这个题挺难改 你需要用到 循环矩阵快速幂,矩阵快速幂优化,打表找规律的基础 题解 首先我们可以列出来一个普通的dp式子 设f为第i次操作,操作后x变为j的概…

es5直接引入html文件,ES6+转ES5(webpack+babel、指定多个js文件、自动注入)

接续上篇ES6转ES5&#xff0c;本篇将使用webpack和babel将多个不同目录下指定的多个ES6语法的js文件编译为ES5&#xff0c;并将编译后的文件配置注入对应的html文件。一、新建项目&#xff0c;目录如下二、执行命令初始化项目cnpm init -y执行成功后会生成文件&#xff1a;pack…

在Spring MVC中,InternalResourceViewResolver做什么?

InternalResourceViewResolver是Spring MVC框架中ViewResolver一个实现&#xff0c;它将逻辑视图名称&#xff08;例如“ hello”&#xff09;解析为内部物理资源&#xff08;例如Servlet和JSP文件&#xff0c;例如放置在WEB-INF文件夹下的jsp文件&#xff09;。 它是UrlBasedV…

深圳敏捷云计算机科技,敏捷云 | 关于我们 | 敏捷云

(93) Afghanistan(355) Albania(213) Algeria(1) American Samoa(376) Andorra(244) Angola(1) Anguilla(1) Antigua(54) Argentina(374) Armenia(297) Aruba(61) 澳大利亚(43) Austria(994) Azerbaijan(973) Bahrain(880) Bangladesh(1) Barbados(375) Belarus(32) Belgium(50…

算法:用户喜好--Map与List配合下的查找

提示&#xff1a;在算法处理过程中&#xff0c;未必就要将出现在前面的作为关键字检索。比如本题&#xff0c;非得先去检索范围&#xff0c;再去判断范围中key的个数。反其道而行&#xff0c;把输入的数字当作关键字&#xff0c;组成Map package test;import java.util.ArrayLi…

带有Gradle的Spring Boot Web应用程序

1.简介 在继续使用Gradle创建演示Spring Boot Web应用程序之前&#xff0c;我假设我们已经准备好使用Gradle设置 。 摇篮设置指南 Gradle官方网站 2.创建演示应用程序 现在我们已经准备好安装插件&#xff0c;创建一个新的Gradle项目&#xff0c;如下所示– 单击下一步 &am…

html定义变量的语句规则,前端规范

前言&#xff1a;不规范的开发不仅使日后代码维护变的困难&#xff0c;同时也不利于团队的合作。下面列出了前端开发规范通用规范&#xff1a;1、前端工具统一sublime text&#xff0c;配置信息统一&#xff0c;如下&#xff1a;{"caret_style": "phase",&…

云技术-SaaS架构初步理解

最近公司准备整一个SaaS的东西。有幸参入这一块东西的搭建&#xff0c;借着這个机会也重新好好梳理了一下对SaaS的认识。今天整理一下&#xff01; 一、云计算与SaaS 说起SaaS&#xff0c;就得先说说云计算了。关于云计算分为三层&#xff0c;基础设施在最下端&#xff0c;平台…

primefaces_轻量级Web应用程序框架:PrimeFaces(JSF)+ Guice + MyBatis(第2部分)

primefaces在这一部分中&#xff0c;我将继续演示JSF&#xff0c;Guice和MyBatis的集成。 在持久层中使用DBCP连接池和MYSQL数据库。 看一下第1部分 。 在上一篇文章中 &#xff0c;我们创建了一个ServletContextListener。 现在&#xff0c;我们只需要在contextInitialized方…

html三元运算符 模板,AngularJS模板中的三元运算符

小编典典更新 &#xff1a;Angular1.1.5添加了一个三元运算符&#xff0c;因此现在我们可以简单地编写如果您使用的是较早版本的Angular&#xff0c;则有两个选择&#xff1a;(condition && result_if_true || !condition && result_if_false){true: result_if…

pycharm 更改创建文件默认路径

pycharm 更改创建文件默认路径 1、操作 依次找到以下路径修改为自己想要的路径即可&#xff1a;PyCharm——>Settings——>Appearance&Behavior——>System Setting——>Project Opening——>Default directory 2、图示 posted on 2019-07-29 14:18 初妍 阅…

Spring Security和多个过滤器链

Spring Security是一项非常有用的技术。 它使您可以保护应用程序而不会过于侵入&#xff0c;并允许插入许多不同的身份验证机制。 另一方面&#xff0c;要使用它并不是那么容易&#xff0c;并且每次接触它时我都必须重新学习这些工具之一。 在这篇文章中&#xff0c;我将介绍Sp…