java 内存 四_java最终化的内存保留问题(4)

四、

一种代替最终化的选择

在前面一节中的示例还存在一种不确定性可能:JVM并不能保证它在最终化队列中调用对象的终结器的顺序。而来自于所有类(应用程序,库,等等)的终结器都是被同等对待的。因此,一个占有大量内存或一种稀有的本地资源的对象可能受阻于终结化队列-它们排在那些终结器进度缓慢的对象之后(不一定是恶意;也许由于懒惰的编程所致)。

看完上面达内培训老师分享的的第一段内容之后大家是不是已经知道今天我们要为大家分享什么内容了那?

为了避免这种类型的不确定性,你可以使用弱参考来代替最终化,例如使用死后钩子(postmortem

hook)。如果用这种方式,你可以完全控制怎样优先化本地资源的回收问题,而代替依赖于JVM完成这件事情。下面的示例展示了这一技术:

final

class NativeImage3 extends WeakReference {

private

int nativeImg;//指向本地图像数据

//它释放本地图像;随后对它的调用将被忽略

private

native void disposeNative();

void

dispose() {

disposeNative();

refList.remove(this);

}

static

private ReferenceQueue refQueue;

static

private List refList;

static

ReferenceQueue referenceQueue() {return refQueue;}

NativeImage3(Image3

img) {

super(img,

refQueue);

refList.add(this);

}

}

public

class Image3 {

private

NativeImage3 nativeImg;

private

Point pos;

private

Dimension dim;

public

void dispose() { nativeImg.dispose(); }

}

Image3与Image2相同。NativeImage3相似于NativeImage2,但是它的最后清理依赖于弱参考而不是最终化。NativeImage3扩展WeakReference,其参考是与之相关联的Image3实例。请记住,当一个参考对象的参考(此时是WeakReference)成为不可达的时,该参考对象就被添加到与之相关联的参考队列上。把nativeImg嵌入到参考对象本身就保证JVM会正确地把所需要的加入到队列中(见图6)。再强调一下,NativeImage3不应该成为Image3的一个子类,这是基于前面所述原因。

图6.把nativeImg嵌入到Reference对象本身

你可以决定是否一参考对象的参考物已经被垃圾收集器以两种方式回收:显式地,在参考对象上调用get()方法;隐式地,通过观察参考对象已经在相关联的参考队列中排队来实现。本示例中只使用了后者。

注意,参考对象仅能被垃圾收集器所发现并且被添加到它们的相关联的参考队列-只有它们本身是可达的时候。否则,它们就象任何其它不可达的对象一样被简单地回收。这就是为什么你把所有的NativeImage3实例添加到该静态链表(实际上,任何数据结构都会满足):为了确保它们保持为可达的并且当它们的参考物成为不可达的时被处理。当然,你还必须确保当你释放它们时(这是通过dispose()方法来实现的)你从该列表中删除了它们。

当在一个Image3实例上显式地调用dispose()方法时,在该实例上不会发生随后的最后清理;正确情况下也是这样,因为这里不需要任何东西。这个dispose()方法从静态列表中删除NativeImage3实例,这样当它的相应的Image3实例成为不可达的时它就是不可达的。并且,如前所述,不可达的参考对象并不被添加到它们相应的参考队列。相反,在所有前面的使用了最终化的示例中,可最终化的对象将总是被作最终化考虑-当它们成为不可达的时候,无论你是否已显式地释放它们相关联的本地资源。

JVM将保证,当通过垃圾收集器发现一个Image3实例是不可达的时候,它会把它的相应的NativeImage3实例添加到它的相关联的参考队列上去。然后,由你负责把它从队列中删除并释放它的本地资源。这可以通过在一个"清理"线程中,用一个如下的循环来实现:

ReferenceQueue

refQueue =NativeImage3.referenceQueue();

while

(true) {

NativeImage3

nativeImg =(NativeImage3) refQueue.remove();

nativeImg.dispose();

}

这是一个过于简单的实例。高级开发者能另外根据它们如何需要优先化清理来确保不同参考对象关联于不同的参考队列。并且一个单个的"清理"线程可以查询所有可用的参考队列和根据要求的优先级来从队列中删除对象。另外,你可以选择展开(spread

out)回收资源,这样它就会给应用程序带来更少的危险性。

尽管用这种方式清理资源与使用最终化相比,明显是更复杂些,但是这也是一种更为有力量和更为灵活的方式,而且可以最小化大量的与使用最终化相关的不确定性。另外,这种方式还十分相似于最终化实际在JVM内实现的方式。对于那些显式地使用很多本地资源并且需要更多控制的工程,我推荐对它们进行清理时使用这一方法。而只要小心地使用最终化对于大多数另外的工程来说也就足够了。

注意:本文仅讨论了两种类型的在使用最终化时产生的问题,也就是内存和资源保留问题。最终化和参考类的使用也能带来很微妙的同步问题。要想详细了解这一点,可以参考Read

Hans-J.Boehm的《最终化,线程和基于Java技术的内存模型》一文。

五、仅在必要时才使用最终化

本文简短描述了最终化是怎样在JVM中实现的。然后给出了有关内存是怎样不必被可最终化的对象所保留的示例并且概括了这种问题的解决方案。最后,我描述了一个方法-它使用弱参考来代替-这允许你用一种更为灵活和可预测的方式来执行最后清理。

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

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

相关文章

基于Spring Boot不同的环境使用不同的配置方法

原文路径:http://www.jb51.net/article/132589.htm ---------------------------------------- 默认是profile为dev,可以修改 spring 多文件配置: 1、properties文件 2、YAML文件 一、properties文件 在 Spring Boot 中, 多环境配…

java set方法赋值_java方面:private属性,没有set方法,只有get方法,如何给这个属性赋值?...

富国沪深用反射吧,然后设置setAccessible为true就可以了,如下:public class Test {private String readOnly;public String getReadOnly() {return readOnly;}public static void main(String[] args) throws SecurityException, NoSuchField…

SpringBoot项目在IntelliJ IDEA中实现热部署

spring-boot项目热部署idea工具&#xff1a; &#xff08;1&#xff09;、pom文件引入&#xff1a;都需要为true<!-- 热部署模块 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId…

java nio 对消息分片_Java NIO:应用

Java NIO 是一种非阻塞的、面向块而非字节的 IO 方式。虽然 Java 的传统 IO 也进行了一些基于 NIO 的改造&#xff0c;NIO 仍然能够带来许多优势。面向流的 IO 方便我们一个字节一个字节地处理数据&#xff0c;有利于实现过滤等功能&#xff0c;更加优雅和简单。相应地&#xf…

使用Notepad++来比较文件

原文连接&#xff1a;https://blog.csdn.net/sanqima/article/details/50467154 -----------------------------------------------------------------------------Notepad&#xff0c;也叫npp&#xff0c;是一款类似于记事本的开源小软件。它运行便携&#xff0c;体积小、资源…

利用lamda函数 的函数式编程 实现scrapy审计外网安全问题

2019独角兽企业重金招聘Python工程师标准>>> import scrapy from scrapy.spiders import Spiderdef parse_response(response, ip_in):title response.xpath("/html/head/title").extract()[0]filename quotes.txtwith open(filename, a) as f:f.write(…

Linux服务器上新增开放端口号

原文连接&#xff1a; https://blog.csdn.net/u012562106/article/details/52882666 ---------------------------------------开放端口的方法&#xff1a; 方法一&#xff1a;命令行方式 1. 开放端口命令&#xff1a; /sbin/iptables -I INPUT -p tcp --dport 8…

return ,continue,break的用法与区别总结

1、return 语句的作用 (1) return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行。 (2) return 返回一个值给调用该方法的语句&#xff0c;返回值的数据类型必须与方法的声明中的返回值的类型一致&#xff0c;可以使用强制类型转换来是数据类型一致。 (…

linux java -xms_为什么JVM比指定的-Xms消耗更少的内存?

我的问题是 Headers &#xff0c;我通过搜索获得了一些知识&#xff1a;但还是不知道为什么&#xff0c;有些可以提供一些帮助吗&#xff1f;这是我在Ubuntu12.04(64位)上的测试运行JDK 1.7.0_04 . 和顶部显示如下&#xff1a;PID USER PR NI VIRT RES SHR S %CPU %MEM TIME CO…

Jquery的一些方法

$.trim(str);说明&#xff1a;去掉字符串首尾空格。转载于:https://www.cnblogs.com/gygtech/p/9552538.html

清除nginx服务器网站缓存数据

原文连接&#xff1a;https://blog.csdn.net/Crabime/article/details/51883028?locationNum2&fps1 -------------------------------------公司网站上线之后后面老是出现一些小的bug&#xff0c;但是这些bug在vi上改了之后打开更改的网页却发现并没有更改&#xff0c;goo…

linux安装指定版本python_ubuntu多版本python为指定版本python安装库

当安装了多个版本的Python时&#xff0c;比如一个python2.7&#xff0c;一个python3.5&#xff0c;需要为某个python版本安装库时如何精准的指定python版本呢。网上多数回答都是用到pyenv、virtualenv之类&#xff0c;看了下感觉跟我的预期不一致。因为PyCharm已经可以管理多个…

Linux 如何通过某一台服务器调用执行多台远程服务器上的脚本,结果显示在本地?...

现在都流行自动化运维了&#xff0c;可能目前技术不够&#xff0c;很多自动化工具还不怎么会用&#xff0c;所以本次只是通过ssh来实现功能。 说明&#xff1a;自己写的一个简单脚本&#xff0c;只是实现了基础功能&#xff0c;还有待优化。 一共三台机器&#xff1a; master&a…

linux下查看磁盘分区的文件系统格式

原文链接&#xff1a; https://www.cnblogs.com/youbiyoufang/p/7607174.html ------------------------------------------------------------------------- df -T 只可以查看已经挂载的分区和文件系统类型。 Filesystem Type 1K-blocks Used Available Use% Mounted on/dev/s…

ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)

Linux下mysql的安装&#xff0c;真是不同Linux环境&#xff0c;各种问题。步骤&#xff1a; 1、暂停mysql服务 service mysqld stop2、设置mysql模式# mysqld_safe --usermysql --skip-grant-tables --skip-networking & 3、clone session&#xff0c;新窗口# mysql -u roo…

mysql 跳表 b 树_简单谈谈Mysql索引与redis跳表

摘要面试时&#xff0c;交流有关mysql索引问题时&#xff0c;发现有些人能够涛涛不绝的说出B树和B树&#xff0c;平衡二叉树的区别&#xff0c;却说不出B树和hash索引的区别。这种一看就知道是死记硬背&#xff0c;没有理解索引的本质。本文旨在剖析这背后的原理&#xff0c;欢…

(Ajax)axios源码简析(三)——请求与取消请求

传送门&#xff1a; axios源码简析&#xff08;一&#xff09;——axios入口文件axios源码简析&#xff08;二&#xff09;——Axios类与拦截器axios源码简析&#xff08;三&#xff09;——请求与取消请求请求过程 在Axios.prototype.request中我们看到&#xff0c;要先通过请…

Windows配置tomcat环境

1、安装JDK 参考教程&#xff1a; https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.htmlCLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarCLASSPATH这个环境变量一定要配好&#xff0c;否则tomcat起不来&#xff0c;直接复制上面的内容&#xff0c;…

java 抽奖 高并发处理_如何设计高并发下的抽奖?

关于抽奖,需要考虑的点有很多,这里稍微整理了下主要需要考虑以下三点:用户抽奖次数限制奖品数量限制奖品发放的分布中奖的概率的可控性用户抽象次数限制一个用户必须限制抽奖的次数,而同一个用户的并发几率其实是很小的,所以这里可以用悲观锁来控制用户的抽奖次数。奖品数量限制…

WPF圆角按钮与触发颜色变化

原文:WPF圆角按钮与触发颜色变化<Button x:Name"button1" Content"按钮1" Margin"10,10,0,0" Cursor"Pen"><Button.Template><ControlTemplate><Border CornerRadius"15,15,15,15"><Border.Back…