Java 强引用、软引用、弱引用、虚引用 和垃圾回收器的关系以及调优原理_java 软引用实现原理_Painter_c的博客-程序员秘密

技术标签: java  Java对象引用类别  Java基础  垃圾回收  JVM调优  

一、背景

大家知道Java是运行在虚拟机上的高级语言,而对于虚拟机,其中有一个特别重要的功能就是垃圾回收器(GC),通过GC机制Java程序可以非常智能的对垃圾进行回收,从而实现非常智能的内存管理,而不用向C或C++一样需要十分谨慎的自己去处理内存问题,从而避免了很多不必要的麻烦。那么GC机制是如何实现的呢?作为GC工作的主战场JVM 的堆内存,是如何去处理那些过期或者在资源紧缺的情况下对对象的处理呢?下面就引出了一个概念,Java对象的引用级别。


二、Java 引用的类别

1 、强引用

只要程序通过 new 关键字创建了对象,那么垃圾回收期永远不会进行对对象的回收,除非是系统内存不够,即便如此,JVM也就只是抛出OutOfMemory()异常,当然如果对象的引用被释放后。这个对象将会被释放掉。那么如何清空这个对象的引用呢?对象的引用是存放在JVM的栈内存中,所以我们清空栈里面的引用自然就清除了这个对象所占用的内存空间。

2 、软引用

非必须引用,当内存资源不够即将溢出时,这个时候GC将会对对象的内存空间进行回收,从而避免内存溢出错误的发生。如何实现软引用:

Object obj = new Object();

SoftReference<Object> sf  = new SoftReference<Object>(obj);

obj = null ;

sf.get(); // 这个时候sf是obj对象的一个软引用,通过get()方法可以获取到这个对象,当内存不足的时候可能返回 null ;

使用场景:当用户需要实现类似缓存的功能,在内存足够的情况下直接通过软引用取值,无需从繁忙的真实来源查询数据,提升速度;当内存不足时,自动删除部分缓存数据,从真正的来源查询相关数据。

3 、弱引用

第二次垃圾回收时回收,不管当前内存资源是否充足,这就是传说中的躺枪吧。。。。 如何实现弱引用:

Object obj = new Object ();

WeakReference<Object> wf = new WeakReference<Object>();// 创建弱引用对象

obj = null ;

wf.get(); // 有的时候回返回null

wf.isEnQueued(); // 返回是否被垃圾回收器标记为即将回收的装状态
弱引用主要用于监控对象是否已经被垃圾回收器标记为即将回收的垃圾,可以通过弱引用的isEnqueued方法返回对象是否被垃圾回收器标记。
4、虚引用(幽灵引用)
obj = null ;
pf.isEnQueued();//返回对象是否已经被清理的状态
虚引用主要用于检测对象是否已经从内存删除。

虚引用是话语权级别最低的引用了,只要垃圾回收开始工作,那么虚引用就会被回收。 实现方式:

Object obj = new Object ();

PhantomReference<Object> pf = new PhantomReference<Object>(obj);

pf.get();//永远返回null

三 、开发实战

作为一个初级的Java开发工程师,可能永远不会考虑JVM的内存问题,但是偶尔大家可能还是会出现OutOfmemory 错误的情况,例如部署一个较大的Tomcat

web服务其实在这个时候大家不需要惊慌,通常我们可以配置Tomcat的配置文件增大内存,或者JVM的内存设置,同时我们还可以通过JVM的GC机制来对程序进行一

定的优化,例如使用软引用,可以一定程度的促进GC的回收,从而避免内存溢出的情况。

尤其是在Android程序的开发中,由于本身硬件资源的短缺,我们更加要学会是使用这些机制去优化我们的程序。

例如:1、图片加载的时候出现内存溢出的情况。

四 、扩展

JVM的GC机制固然智能,降低了程序员的开发难度,但是与此同时也造成一些额外的不良体验,JVM的垃圾回收器主要负责:分配内存,确保被引用的对象不被

回收以及不被引用的对象及时被清理。其实他是一项非常复杂而且耗时的操作,如果JVM花费过多的时间在垃圾回收上,势必会影响程序的性能。所以当GC器开

始工作的时候整个JVM的程序其实是会产生短暂暂停,也就是大家通常所说的卡顿现象。这也就是为什么Android手机不管内存升级到多大还是会产生卡顿的原因,

因为这是Android系统的语言特性,没有办法避免。当然随着技术的发展现在Android系统是越来越流畅,很多的JVM调优机制都可以让我们的程序运行的更加流畅,

用户几乎察觉不到卡顿的现象,其实从底层的原理上来讲只要我们促进GC器工作的间隔越小,工作时间越短,那么对于用户的体验就越好。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a568418299/article/details/78914637

智能推荐

什么是深度学习?其工作原理是什么?_深度学习的概念和原理_daydayup0606的博客-程序员秘密

什么是深度学习?简单来说,深度学习就是样本研究。从最基本的概念上看,深度学习就是机器学习的一种方法,教计算机筛选输入的信息,进而对信息进行预测和分类。其观察结果可以通过图片、文字或声音的方式呈现。深度学习的灵感来源于人脑过滤信息的方式。其初衷是通过模拟人脑运行模式来做些不一样的事情。这是正儿八经/真实的人工神经网络。人脑中有大约1亿个神经元。每个神经元都与另外约10万个同类相连,人类现在正试图将类似的工作原理应用到机器上。人脑中的神经元分为胞体(body),树突(dendrites)和轴突(a

Hive分析窗口函数(三) LAG,LEAD,FIRST_VALUE,LAST_VALUE_小江_xiaojiang的博客-程序员秘密

接上篇Hive分析窗口函数(二、三) NTILE,ROW_NUMBER,RANK,DENSE_RANK继续学习这四个分析函数。注意: 这几个函数不支持WINDOW子句。(什么是WINDOW子句,Hive分析窗口函数(一)SUM,AVG,MIN,MAx)Hive版本为 apache-hive-0.13.1数据准备:cookie1,2015-04-10

Python编译时提示错误IndentationError: unexpected indent_indentationerror是什么意思_LittleGiantWang的博客-程序员秘密

新手小白刚开始学习Python,尝试想打印一句话,运行时提示 第19行 有个错误 IndentationError: unexpected indent print('a')如上所示,indentation是缩进的意思。unexpected indent 就是说第二行这里存在一个“意外的”缩进。也就是说,这里的问题就是指“print”是一个意外的缩进。可以看到第19行是缩进了一个字符位。百度了下,发现是需要取消缩进顶格写就可以了。print('a')小结:在python中,每一句代码

Flash获取监控摄像头信号(转)_摄像头上的flash是什么意思_he_wen_jian的博客-程序员秘密

普通WEB摄像头的“自动光圈”会在环境光线发生变化后自动调节光圈大小,这是视频互动最忌讳的情况,所以我的所有项目都基于专业的监控摄像头了。可惜Flash却得不到来自监控卡的视频信号,解决的办法就是不再用Flash做视频互动,至少以前是,呵呵。最近一个激光互动游戏是在Flash中完成的,几经修改后,WEB摄像头已经不能胜任,如果它不能获得监控卡的视频信号,这个作品就只能夭折或在效果和灵敏度上

修改tomcat命令窗口的名字_tomcat修改服务名称_wwwcomcn123的博客-程序员秘密

在运行多个tomcat窗口的时候,可以通过修改tomcat命令窗口的名字来区分不同的tomcat,修改如下:找到tomcat下面的这个文件:tomcat_home\bin\catalina.bat 搜索到:set _EXECJAVA=start "Tomcat" %_RUNJAVA% 将"Tomcat"修改成想替换的名称即可

随便推点

前端讲义59_AngularJS模块与控制器_木生火的博客-程序员秘密

我们知道在HTML中使用ng-app指令,即可定义一个Module(模块)。日常我们把应用拆分为一个个的小模块,模块之间相互依赖,这样各个功能可以非常方便重用和测试。模块有两种:匿名模块 &lt;div ng-app&gt;...&lt;/div&gt; AngularJS可自动加载并创建AngularJS模块命名模块 &lt;div ng-app=" HR_emp"&gt;......

Object-C之NSArray用法_东南一叶的博客-程序员秘密

// 类方法创建数组 NSArray *array1 = [NSArray arrayWithObject:@"obj"]; NSArray *array2 = [NSArray arrayWithObjects:@"obj1",@"obj2",@"obj3",@"obj4", nil]; NSArray *array3 = [NSArray arra

【Nav2中文网】七、配置指南(三)行为树XML节点 之 装饰插件--RateController_鱼香ROS的博客-程序员秘密

RateController [待校准@2405]限制其子节点的滴答率的节点。滴答率可以作为参数提供给节点。当节点没有勾选其子节点时,它返回正在运行。目前,在导航堆栈中, RateController 用于调整 ComputePathToPose 和 .

[题记-动态规划]打家劫舍——LeetCode_澄澄澄澄橙的博客-程序员秘密

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。示例 1:输入: [1,2,3,1]输出: 4解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4 。示例 2:输.

推荐文章

热门文章

相关标签