【转】Java高级进阶学习-Java的内存回收(3)

(3)弱引用
  弱引用与软引用有点相似,区别在于弱引用所引用对象的生存期更短。弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存。当然,并不是说当一个对象只有弱引用时,它就会立即被回收,正如那些失去引用的对象一样,必须等到系统垃圾回收机制运行时才会被回收.

下面程序示范了弱引用所引用对象也会被系统垃圾回收的过程.
import java.lang.ref.*;
import java.util.*;
public class WeakReferenceTest
{
public static void main(String[] args) throws Exception
{
//创建一个字符串对象
String str = new String("网络时空");
//创建一个弱引用,让此弱引用引用到"网络时空"字符串
WeakReference<String> wr = new WeakReference<String>(str); //①
//切断str引用和"网络时空"字符串之间的引用
str = null; //②
//取出弱引用所引用的对象
System.out.println(wr.get()); //③

List<String> list=new ArrayList<String>();
list.add(wr.get());

//强制垃圾回收
System.gc();
System.runFinalization();
//再次取出弱引用所引用的对象
System.out.println(wr.get()); //④
}
}

运行结果如下

Java高级进阶学习-Java的内存回收(3)

 

说明如下
上面程序创建了一个“网络时空”的字符串对象,并让str引用变量引用它。执行①行处代码时,系统创建了一个弱引用对象,并让该对象和str引用同一个对象。当程序执行到②行代码时,切断了str和"网络时空"字符串对象之间的引用关系,此时系统图如下所示
内存中分布效果图如下

Java高级进阶学习-Java的内存回收(3)


  从此内存中图示可以看出,此时“网络时空”字符串对象只有一个弱引用对象引用它,程序依然可以通过这个弱引用对象来访问字符串常量,程序中③行代码依然输出“网络时空”,接下来程序强制垃圾回收,如果系统垃圾回收机制启动,只有弱引用的对象就会被清理掉。当程序执行④行代码时,通常就会看到输出null,这表明该对象已经被清理掉了

总结说明:

1.弱引用具有很大的不确定性,因为每次垃圾回收机制执行时都会回收弱引用所引用的对象,而垃圾回收机制的运行又不受程序员的控制,因此程序获取弱引用所引用的java对象时必须小心空指针异常,通过弱引用所获取的java对象可能是null

2.由于垃圾回收的不确定性,当程序希望从弱引用中取出被引用对象时,可能这个被引用对象已经被释放了。如果程序需要使用被引用的对象,则必须重新创建该对象,这个可能可以采用如下风格的代码完成。

伪码形式表示如下

//取出弱引用所引用的对象

obj=wr.get();

//如果取出的对象为null

if(obj==null)

{

  //重新创建一个新的对象,将其使用强引用来引用它

obj=recreateIt();

//取出弱引用所引用的对象,将其赋给wr变量

wr=new WeakReference(obj);

}

...//操作obj对象

//再次切断obj和对象之间的关联

obj=null;

 

 

(4)虚引用
  软引用和弱引用可以单独使用,但虚引用不能单独使用,单独使用虚引用没有太大的意义。虚引用的主要作用就是跟踪对象被垃圾回收的状态,程序可以通过检查虚引用关联的引用队列中是否包含指定的虚引用,从而了解虚引用所引用的对象是否将被回收.
  引用队列由java.lang.ref.ReferenceQueue类表示,它用于保存被回收对象的引用。当把软引用,弱引用和引用队列联合使用时,系统回收被
引用的对象之后,将会把被回收对象对应的引用添加到关联的引用队列中。与软引用和弱引用不同的是,虚引用在对象被释放之前,将把它对应的虚引用添加到关联的队列中,这使得可以在对象被回收之前采取行动。
虚引用通过PhantomReference类实现,它完全类似于没有引用。虚引用对对象本身没有大的影响,对象甚至感觉不到虚引用的存在。如果一个
对象只有一个虚引用,那它和没有引用的效果大致相同。虚引用主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,虚引用必须和队列ReferenceQueue联合使用.

  下面程序与上面程序基本类似,只是使用了虚引用来引用字符串对象,虚引用无法获取它引用的对象,下面程序还将和引用队列结合使用,可以看到,被虚引用所引用对象被垃圾回收后,虚引用将被添加到引用队列中。

import java.lang.ref.*;
public class PhantomReferenceTest
{
public static void main(String[] args)
throws Exception
{
//创建一个字符串对象
String str = new String("网络时空");
//创建一个引用队列
ReferenceQueue<String> rq = new ReferenceQueue<String>();
//创建一个虚引用,让此虚引用引用到"网络时空"字符串
PhantomReference<String> pr =
new PhantomReference<String>(str , rq);
//切断str引用和"网络时空"字符串之间的引用
str = null;
//试图取出虚引用所引用的对象,
//程序并不能通过虚引用访问被引用的对象,所以此处输出null
System.out.println(pr.get()); //①
//强制垃圾回收
System.gc();
System.runFinalization();
//取出引用队列中最先进入队列中引用与pr进行比较
System.out.println(rq.poll() == pr); //②
}
}

Java高级进阶学习-Java的内存回收(3)

 

  因为系统无法通过虚引用来获得被引用的对象,所以执行①处的输出语句,程序将输出null(即使此时未进行强制垃圾回收)。当程序强制垃圾回收后,只有虚引用引用的字符串对象将会被垃圾回收,当被引用的对象被回收后,对应引用将被添加到关联的引用队列中,因而将在②处代码处看到输出true.

 

【JVM学习笔记】内存回收与内存回收算法 就哪些地方需要回收、什么时候回收、如何回收三个问题进行分析和说明 一、相关名词解释 垃圾收集常用名词 二、哪些地方需要回收 本地方法栈、虚拟机栈、程序计数器 方法区 Java堆 三、什么时候回收 内存能否被回收 内存中的引用类型 引用计数算法 可达性分析算法 内存何时被回收(Hotspot) 四、如何回收 垃圾回收理论 Generational Collection——分代收集理论 JVM堆中的分代 垃圾回收算法 垃圾回收算法的类型 标记-清除算法 Mark-Sweep 标记-复制算法 Mark-Copying 标记-整理算法 Mark-Compact 标记-整理算法 M 阅读详情

相关推荐

Java的内存回收机制

在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险。但是,也正因为内存管理完全由JVM负责,所以也使Java很多程序员不再关心内存分配,导致很多程序低效,耗内存。因此就有了Java程序员到最后应该去了解JVM,才能写出更高效,充分利用有限的内存的程序。

asdfgha14的博客 756

Java 2 引用类使用指南

Peter Haggar(haggar@us.ibm.com)高级软件工程师,IBM 公司Java 2 平台引入了 java.lang.ref 包,其中包括的类可以让您引用对象,而不将它们留在内存中。这些类还提供了与垃圾收集器(garbage collector)之间有限的交互。Peter Haggar 在本文中分析了 SoftReference、WeakReference 和 Phantom

Coolingverse 专栏 1306

4 轴穿越机 Mark5 机架全解析:从历史演进到电机桨叶选型指南

本文围绕 4 轴穿越机 Mark5 机架展开,先介绍其发展历程(2018 年初代到 2023 年五代,迭代优化轻量化、刚性与兼容性),再明确其核心参数(轴距 220mm、兼容 4-6 寸桨等)对电机桨叶的约束。 详解电机(KV 值、尺寸、推力等)与桨叶(尺寸、螺距、材质等)选型要点及匹配原则(高 KV 配小桨、低 KV 配大桨),给出推重比、功率等理论计算公式,结合新手练习、花飞、竞速、航拍等场景提供具体选型案例,最后提及安全、成本、法规等注意事项,为爱好者提供全面选型参考。

bother3000的博客 1901

java中的引用类型(java疯狂笔记)

import java.lang.ref.*; class TestPhantomReference { public static void main(String[] args)throws Exception { String str = new String("hello,world"); //创建一个引用队列 ReferenceQueue rq = new Refe

牧羊少年奇幻之旅 629

保姆级避坑指南:在openEuler 22.03 LTS上用kubeadm 1.32.2部署K8s集群(含阿里云镜像加速)

本文提供在openEuler 22.03 LTS上使用kubeadm 1.32.2部署Kubernetes集群的详细指南,涵盖系统准备、容器运行时适配、kubeadm配置及集群初始化等关键步骤。特别针对openEuler系统的特殊性,解决软件源配置、cri-dockerd编译安装、阿里云镜像加速等常见问题,帮助用户高效完成K8s集群部署。

weixin_28312391的博客 273

开源DIY龙门架:从零构建可编程运动控制平台

运动控制是自动化与机器人技术的核心基础,它通过精确指令驱动执行机构,实现物体的定位与轨迹规划。其原理通常涉及控制器、驱动器、电机与传动机构的协同工作,核心价值在于将数字指令转化为精准的物理运动,从而解放人力并提升作业一致性。在工业自动化、桌面制造(如3D打印、激光雕刻)及教育机器人等领域应用广泛。本文聚焦于一个具体的工程实践案例:使用**铝型材**、**3D打印**零件、Arduino控制器及步进电机,从机械结构设计、电路连接到代码编写,手把手教你打造一个模块化、可扩展的开源龙门架系统。该系统不仅成本可控,

weixin_33168937的博客 620

谈谈Fragment的构造函数、重新创建(recreate)及相关

本文分享一些Android Fragment使用经验和一些使用注意点,对于有一定开发经验的朋友应该会比较有帮助。

小飞的技术博客 1万+

Linux环境下使用线程方式操作UART读写功能

本文介绍Linux环境下使用线程方式操作UART的方法,实现了串口打开,关闭,发送数据,接收数据功能,还编写测试代码,验证该功能。

mftang的博客 2079

检索被引用对象的风格(WeakReference)

Ref: http://blog.youkuaiyun.com/zhangzhaokun/article/details/5083415 BAD! obj = wr.get(); if (obj == null) {   wr= new WeakReference(recreateIt());  //1   obj= wr.get();                        //2 }

kdevn的专栏 477

从统一入口到运营中枢:全面看懂 SAP for Me 的能力边界、使用方式与项目价值

SAP for Me 是 SAP 推出的统一工作平台,旨在整合原本分散在多个系统中的关键信息与操作。它将许可证管理、系统状态、支持工单、维护合同、产品路线图等核心功能集中到一个界面,为不同角色提供定制化视图。平台包含多个功能模块:Home 作为个性化工作台展示待办事项与风险;Calendar 整合各类维护事件与关键时间节点;Reporting 提供跨域分析与趋势洞察;Finance & Legal 管理订单、发票与合规事项;Portfolio & Products 则展示产品全景与路线图。该

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 121

Tmux学习总结

Tmux 重要概念 使用 Tmux 的时候千万不要去背指令,所有的指令都可以在 .tmux.conf 配置文件中绑定自己顺手的快捷键,也可以配置开启鼠标。 这个是我的配置文件:https://github.com/zuorn/tmux.conf 在Tmux逻辑中,需要分清楚Server > Session > Window > Pane这个大小和层级顺序是极其重要的,直接关系到工作效率: Server:是整个tmux的后台服务。有时候更改配置不生效,就要使用tmux kill-

满目星辰 579

Java内存模型与垃圾回收实战进阶

1.背景介绍 1. 背景介绍 Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)的一个核心概念,它定义了Java程序中各种变量(线程共享变量)的访问规则,以及在多线程环境下的内存可见性、有序性等。Java内存模型的目的是为了解决多线程编程中的内存一致性问题,确保程序的正确性和性能。 垃圾回收(Garbage Collection, GC)是Java虚拟...

AI天才研究院 979

把 SAP 配置当成一张地图:用 IMG 把实施、变更与治理串成一条清晰的路

摘要 SAP IMG(Implementation Guide)是SAP实施的核心导航体系,它将客户需求转化为系统配置,提供结构化路径和文档化支持。IMG不是简单的菜单树,而是包含业务落地路径、标准化配置活动和文档化知识的实施语言。通过三种视图(Reference、Enterprise、Project)解决不同管理问题,其中Project IMG尤其重要,可管理项目范围、分工和进度。实际工作中应通过SPRO事务码访问IMG,将探索与执行分开管理。案例显示,跨国企业通过Project IMG可有效控制组织架构

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 229

Java高级进阶学习-Java的内存回收(3)

(3)弱引用   弱引用与软引用有点相似,区别在于弱引用所引用对象的生存期更短。弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统内存是否足够,总会回收该对象所占用的内存。当然,并不是说当一个对象只有弱引用时,它就会立即被回收,正如那些失去引用的对象一样,必须等到系统垃圾回收机制运行时才会被回收.

FlywindMouse的专栏 1144

基于 Simulink 的固态变压器(SST)多级协同控制实战教程

《固态变压器多级协同控制仿真指南》摘要: 本教程详细讲解了基于Simulink的固态变压器(SST)三级架构建模与控制方法。核心内容包含:1)搭建级联H桥整流(CHB)、双有源桥(DAB)和逆变器(VSI)的三级主电路;2)提出创新的多级协同控制策略,通过功率前馈实现输入输出级动态匹配;3)给出系统级功率平衡、单元级均压控制的具体实现方案。教程特别强调解决实际工程中的关键问题:代数环处理、软启动设计和刚性系统求解器选择,并提供了硬件在环(HIL)仿真建议。附带的MATLAB代码示例可直接用于实现电容电压均衡

xiaoheshang_123的博客 120

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java进阶—GC回收(垃圾回收)

垃圾回收(Garbage Collection,GC)是Java虚拟机(JVM)的一项重要功能,用于自动管理程序中不再使用的内存。在Java中,程序员不需要手动释放内存,因为GC会自动检测并回收不再使用的对象,从而减少内存泄漏的风险。

tanmoney的博客 2124

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java 内存 回收_java内存回收

一、为什么需要垃圾回收如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。二、哪些内存需要回收?哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象。那么如何找到这些对象?1、引用计数法这个算法的实现是,给对象中添加一个引用...

weixin_26878995的博客 2300

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Java内存回收机制

C、C++等语言中,内存的分配和释放由程序代码来完成,容易出现由于程序员漏写内存释放代码引起的内存泄露,最终导致系统内存耗尽。 Java代码运行在JVM中,由JVM来管理 堆Heap 内存的分配和回收(Garbage Collection),把程序员从繁琐的内存管理工作中释放出来,更专注于业务开发。Java内存回收工作由标记(识别可回收对象)和回收(释放可回收对象)两个步骤组成。 和程序代码释放内存相比,内存自动管理会占用一部分CPU时间,Stop The World特点回暂停业务程序运行,非常影响执行效率

hequnwang10的博客 6330

Java高级进阶学习-Java的内存回收(2)

阿堂在介绍“强引用,软引用,弱引用,虚引用”之前,前面没有对内存泄露的概念进行说明,这里简单补充说明一下.   内存泄露:程序运行过程中,会不断分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,这就是内存泄漏. (1)强引用   这是java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用

FlywindMouse的专栏 1185

Java进阶——Java内存模型和垃圾回收机制

前言 Java内存模型结构分为 线程共享区:堆、方法区 线程私有区:虚拟机栈、本地方法栈、程序计数器 堆 堆用于存放对象实例和数组,由于堆是用来存放对象实例,因此堆也是垃圾收集器管理的主要区域,故也称为 GC堆。由于现在的垃圾收集器基本都采用分代收集算法,所以堆的内部结构只包含新生代和老年代 新生代:用于存放刚创建的对象以及年轻的对象,如果对象一直没有被回收,生存得足够...

点击置顶文章查看博客目录(全站式导航) 4595

JVM上篇学习3--内存与垃圾回收

JVM上篇学习3–内存与垃圾回收 执行引擎 StringTable 垃圾回收概述

xu_jin_shan的博客 3826

Java知识点小结3:内存回收

Java知识点小结3:内存回收

duke_ding2的博客 1166

【Java进阶营】Java 堆外内存回收原理

堆外内存简介 DirectByteBuffer 这个类是 JDK 提供使用堆外内存的一种途径,当然常见的业务开发一般不会接触到,即使涉及到也可能是框架(如 Netty、RPC 等)使用的,对框架使用者来说也是透明的。 堆外内存优势 堆外内存优势在 IO 操作上,对于网络 IO,使用 Socket 发送数据时,能够节省堆内存到堆外内存的数据拷贝,所以性能更高。看过 Netty 源码的同学应该了解,Netty 使用堆外内存来实现零拷贝技术。对于磁盘 IO 时,也可以使用内存映射,来提升性能。另外,更重要的几乎不

m0_70081047的博客 323

Java 内存分配和回收

Java 内存分配和回收是 Java 虚拟机 (JVM) 自动进行的关键过程,旨在有效地管理内存,防止内存泄漏,并优化程序性能。

m0_69529796的博客 628

java 数组回收_java的内存回收

程序远通过new关键字创建java对象,即视为java对象申请内存空间,Jvm会在对内存中为每个对象分配空间;当一个java对象失去引用时,JVM的垃圾回收机制会自动清除它们,并且回收它们所占的内存空间。对象在内存中的状态:将jvm内存中对象引用理解成一种有向图,把线程对象当成有向图的定点。顶点科大的对象垃圾回收机制不会回收它们;如果某个对象在这个邮箱途中处于不可达状态,认为这个对象不再被引用,接...

weixin_39828331的博客 876
上一篇: 【转】Java高级进阶学习-Java的内存回收(2)
下一篇: 【转】Java高级进阶学习-Java的内存回收(4)
CoderRobin
博客等级 码龄16年 0粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值