java 幽灵引用_Java 幽灵引用的作用

原标题:Java 幽灵引用的作用

来源:imzoer,

blog.csdn.net/imzoer/article/details/8044900

找实习的时候,面试大摩,就遇到了这个问题,当时真不该跟面试官交流这个内容的。

垃圾收集过程中,对象的可触及状态改变的时候,可以把引用对象和引用队列关联起来【这里说的关联,是说垃圾收集器会把要回收的对象添加到引用队列ReferenceQueue】,这样在可触及性发生变化的时候得到“通知”。

当垃圾收集器对加入队列的对象改变可触及性的时候,就可以收到异步通知了。

看下面的代码:

package static_;

import java.lang.ref.PhantomReference;

import java.lang.ref.Reference;

import java.lang.ref.ReferenceQueue;

import java.lang.reflect.Field;

public class Test {

public static boolean isRun = true;

@SuppressWarnings("static-access")

public static void main(String[] args) throws Exception {

String abc = new String("abc");

System.out.println(abc.getClass() + "@" + abc.hashCode());

final ReferenceQueue referenceQueue = new ReferenceQueue();

new Thread() {

public void run() {

while (isRun) {

Object obj = referenceQueue.poll();

if (obj != null) {

try {

Field rereferent = Reference.class

.getDeclaredField("referent");

rereferent.setAccessible(true);

Object result = rereferent.get(obj);

System.out.println("gc will collect:"

+ result.getClass() + "@"

+ result.hashCode() + "t"

+ (String) result);

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

}.start();

PhantomReference abcWeakRef = new PhantomReference(abc,

referenceQueue);

abc = null;

Thread.currentThread().sleep(3000);

System.gc();

Thread.currentThread().sleep(3000);

isRun = false;

}

}

我们用一个线程检测referenceQueue里面是不是有内容,如果有内容,打印出来queue里面的内容。

从这个例子中,我们可以看出来,虚引用的作用是,我们可以声明虚引用来引用我们感兴趣的对象,在gc要回收的时候,gc收集器会把这个对象添加到referenceQueue,这样我们如果检测到referenceQueue中有我们感兴趣的对象的时候,说明gc将要回收这个对象了。此时我们可以在gc回收之前做一些其他事情,比如记录些日志什么的。

感谢蓝大牛分享下面的例子。

在java中,finalize函数本来是设计用来在对象被回收的时候来做一些操作的(类似C++的析构函数)。但是对象被GC什么时候回收的时间,却是不固定的,这样finalize函数很尴尬。虚引用可以用来解决这个问题。

在创建虚引用的时候必须传入一个引用队列。在一个对象的finalize函数被调用之后,这个对象的幽灵引用会被加入到引用队列中。通过检查队列的内容就知道对象是不是要准备被回收了。

幽灵引用的使用并不多见,主要是实现细粒度的内存控制。比如下面代码实现一个缓存。程序在确认原来的对象要被回收之后,才申请内存创建新的缓存。

fadd63b9c2cb000ffa3b0b941ef4043e.png

在上面的代码中,每次申请新的缓存的时候,都要确保之前的字节数组被成功回收。引用队列的remove方法会阻塞直到虚引用被加入到引用队列中。【只有对象在内存中被移除之后才会进入引用队列中】。

不过注意,这种方式可能会导致gc次数过多,程序吞吐量下降。

另外注意,system.gc调用仅仅是建议虚拟机进行回收,并不一定马上会进行gc。返回搜狐,查看更多

责任编辑:

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

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

相关文章

unique_ptr使用简介

我们知道auto_ptr通过复制构造或者通过赋值后,原来的auto_ptr对象就报废了.所有权转移到新的对象中去了.而通过shared_ptr可以让多个智能指针对象同时拥有某一块内存的访问权.但假如我们不希望多个内存块被多个智能指针对象共享,同时又不会像auto_ptr那样不知不觉的就让原来的a…

python访问共享文件夹 exist false_python os.path.exists()对于存在的nfs挂载目录文件失败...

我基本上有一个网站的网站服务器,另一个只存储文件.文件服务器通过挂载其中一个目录连接到主文件服务器.该网站运行Django所以我主要处理python.无论如何,我似乎遇到了一些问题,即文件被报告为不存在,即使它们实际存在.基本上当我打电话时filepath /path/to/file/on/nfs/share…

什么是CouchDB?

※本文对CouchDB的解释是来自Apache CouchDB的官网的译文,如果有什么问题,请指正。 1.CouchDB简介 CouchDB是一种利用JSON文件,javascript作为MapReduce查询,以及常规HTTP作为API的一种数据库系统。 2.CouchDB,一个为W…

java assembly 打包_maven 使用assembly 进行打包的方法

1. pom 中添加assembly 插件要使用assembly 进项编译打包, 首先主要在pom 中的build中添加插件信息, 具体如图下所示:${project.artifactId}src/main/javasrc/main/resourcestrue**/*.xml**/*.properties${profile.dir}trueorg.apache.maven.…

rt5350 中断处理分析

1. arch/mips/kernel/genex.S j plat_irq_dispatch 2. arch/mips/rt2880/irq.c plat_irq_dispatch rt2880_irqdispatch do_IRQ do_IRQ定义在 include/asm-mips/irq.h 这个头文件中,asm-mips这个目录链接到asm这里,所以在 arch/mips/rt2880/ir…

python json数据格式数组内元素递增赋值_利用Python实现JSON格式数据的编码与解码操作...

导读JSON (全称:JavaScript Object Notation )是一种轻量级的数据交换格式,所谓的轻量级,是与 XML 数据结构相比而言的,在描述相同的数据下,JSON 所需的字符比XML 的要少,这就意味着相同意义的数据&#xf…

java注解中可使用对象_Java注解(二):实战 - 直接使用对象列表生成报表...

通过对Java注解(一):介绍,思想及优点学习了解,相信大家对Java注解有一定程度的了解,本篇文章将实战项目中的应用来加深对Java注解的了解。本实例实现根据指定字段的JavaBean,生成对应列的报表。使用Java注解就是方便实现JavaBean与…

ASP.NET WebForm中使用WebApi

添加webapi.dll 可现在添加。 在WebForm使用WebApi需要在全局文件里配置路由。 using System.Web.Routing;protected void Application_Start(object sender, EventArgs e){RegisterRoutes(RouteTable.Routes);}public static void RegisterRoutes(RouteCollection routes){//C…

rt5350 中断初始化

linux 下的中断初始化,实际就是对 irq_desc 这个结构体进行初始化,其中最关键莫过于 irq_flow_handler_t handle_irq 中断处理函数 struct irqaction *action 用户自己设置的处理函数链表,由hand…

VS2010安装异常中断后无法安装的解决方法(安装时发生严重错误)

最近,因为公司开发的需要,对开发环境进行全面的升级,在这其中也遇到了不少问题,在之后将陆续整理出来,以便以后查看。 之前开发环境:ArcGIS9.3,ArcEngine9.3,Oracle10g,A…

python自动下载邮件_python实现邮件自动化

1、自动接收邮件并且下载附件,使用pop3协议。# 接收邮件并下载邮件附件import poplibimport emailimport datetimeimport timefrom email.parser import Parserfrom email.header import decode_headerimport tracebackimport telnetlibimport sys# from email.util…

将5350 i2c clk设置为gpio 中断模式的方法

5350和我之前用的三星和全志的芯片在中断这块有点差别,三星和全志的都是有专门的外部中断管脚,并且每个中断管脚对应一个中断号,对管脚寄存器的配置即irq_desc里chip变量,都是bsp里自带的,我们只需要用request_irq来注…

代码大全 MSIL语言程序设计

.NET平台的编译器会将高级语言(C#,VB.NET,F#)编译成MSIL(微软中间语言)格式。熟悉MSIL语言,可以读懂一些加密程序混淆过的算法,这些算法几乎不能还原成高级语言,但是可以还原成MSIL语言。也可以知道一些高级语言之外的关于CLR的特性&#xff…

python 条件概率_机器学习中的概率问题

机器学习的过程可以理解为计算机通过分析大量的数据获得模型,并通过获得的模型进行预测的过程。机器学习的模型可以有多种表示,例如线性回归模型,SVM模型,决策树模型,贝叶斯模型。概率类型在理解概率模型之前&#xff…

java string 类 上机_java上机试题

请将下列关键字填写到适当的位置中。newextendsimplementsstaticsuperpublicabstractthisimportpackage(1)Fruits;//声明包语句(2)java.util.*;abstractclassFruit//定义抽象类Fruit{D...请将下列关键字填写到适当的位置中。new extends implements static superpublic abstrac…

LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别

LIBRARY_PATH和LD_LIBRARY_PATH是Linux下的两个环境变量,二者的含义和作用分别如下: LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径,例如,指定gcc编译需要用到的动态链接库的目录。 LD_LIBRARY_PA…

下列python语言、返回结果不是uc_MKAN1-UC 5103作业代写、代做Analytics作业、Java,Python,c/c++程序语言作业代做...

MKAN1-UC 5103作业代写、代做Analytics作业、Java,Python,c/c程序语言作业代做日期:2020-05-21 11:08Marketing Analytics Spring 2020 Final ExamMKAN1-UC 5103 Marketing Analytics Spring 2020 Final ExamInstructions (total 3 points):?…

以太网交换机

以太网交换机是基于以太网传输数据的交换机,以太网采用共享总线型传输媒体方式的局域网。以太网交换机的结构是每个端口都直接与主机相连,并且一般都工作在全双工方式。交换机能同时连通许多对端口,使每一对相互通信的主机都能像独占通信媒体…

java中Class对象详解

java中把生成Class对象和实例对象弄混了,更何况生成Class对象和生成instance都有多种方式。所以只有弄清其中的原理,才可以深入理解。首先要生成Class对象,然后再生成Instance。那Class对象的生成方式有哪些呢,以及其中是如何秘密…

python分组求和法_python – 如何将groupby值的总和除以另一个值的count

我想通过’label’和’month’分组来计算每个月和每个标签的销售数量.我正在尝试’groupby和apply’方法来实现这一目标,但不确定如何计算每个标签的月份.比方说,对于标签值AFFLELOU(DOS),我有7个月的两个值.所以,我应该将销售数量相加并除以2.在第9个月和第10个月,我只有一个值…