Effective Java笔记(7)消除过期的对象引用

Unity工业数据可视化:基于ModbusTCP的实时数据通信实战 本文详细介绍了在Unity中实现工业数据可视化的核心方法,重点讲解了基于ModbusTCP协议与PLC等工业设备进行实时数据通信的实战流程。内容涵盖NModbus库的集成、Modbus Slave模拟器的使用、TCP连接的建立与多线程安全通信、数据读写与解析,以及如何将实时数据驱动3D场景,为构建工业数字孪生与监控系统提供完整解决方案。 阅读详情

        当你从手工管理内存的语言(比如 C 或 C++)转换到具有垃圾回收功能的比如 Java 语言时,程序员的工作会变得更加容易,因为当你用完了对象之后,它们会被自动回收 。 当你第一次经历对象回收功能的时候,会觉得这简直有点不可思议 。 它很容易给你留下这样的印象, 认为自己不再需要考虑内存管理的事情了,其实不然 。

请看下面这个简单的战实现的例子:

        这段程序中并没有很 明显的错误 。 无论如何测试,它都会成功地通过每一项测试,但是这个程序中隐藏着一个问题 。 不严格地讲,这段程序有一个“内存泄漏”,随着垃圾回收器活动的增加,或者由于内存占用的不断增加,程序性能的降低会逐渐表现出来 。 在极端的情况下,这种内存泄漏会导致磁盘交换( Disk Paging ),甚至导致程序失败( OutOfMemoryError 错误),但是这种失败情形相对比较少见 。

        那么,程序中哪里发生了内存泄漏呢? 如果一个栈先是增长 ,然后再收缩 , 那么,从栈中弹出来的对象将不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,它们也不会被回收 。 这是因为栈内部维护着对这些对象的过期引用( obsolete reference ) 。 所谓的过期引用,是指永远也不会再被解除的引用 。 在本例中,凡是在 elements 数组的“活动部分”(active portion )之外的任何引用都是过期的 。 活动部分是指 elements 中下标小于 size 的那些元素 。

        在支持垃圾回收的语言中,内存泄漏是很隐蔽的(称这类内存泄漏为“无意识的对象保持”( unintention al object retention )更为恰当) 。 如果一个对象引用被无意识地保留起来了,那么垃圾回收机制不仅不会处理这个对象,而且也不会处理被这个对象所引用的所有其他对象 。 即使只有少量的几个对象引用被无意识地保留下来,也会有许许多多的对象被排除在垃圾回收机制之外,从而对性能造成潜在的重大影响 。

        这类问题的修复方法很简单 : 一旦对象引用已经过期,只需清空这些引用即可 。 对于上述例子中的 Stack 类而言,只要一个单元被弹出栈,指向它的引用就过期了 。pop 方法的修订版本如下所示:

        清空过期引用的另一个好处是,如果它们以后又被错误地解除引用,程序就会立即抛出 NullPointerException 异常,而不是悄悄地错误运行下去 。 尽快地检测出程序中的错误总是有益的。

        当程序员第一次被类似这样的问题困扰的时候,他们往往会过分小心 : 对于每一个对象引用,一旦程序不再用到它,就把它清空 。 其实这样做既没必要,也不是我们所期望的,因为这样做会把程序代码弄得很乱 。 清空对象引用应该是一种例外 , 而不是一种规范行为 。 消除过期引用最好的方法是让包含该引用的变量结束其生命周期 。 如果你是在最紧凑的作用域范围内定义每一个变量,这种情形就会自然而然地发生 。

        那么,何时应该清空引用呢?Stack 类的哪方面特性使它易于遭受内存泄漏的影响呢?简而言之,问题在于,Stack 类自己管理内存 。 存储池( storage pool )包含了 elements 数组(对象引用单元,而不是对象本身)的元素 。 数组活动区域(同前面的定义)中的元素是已分配的( allocated ),而数组其余部分的元素则是自由的( free ) 。 但是垃圾回收器并不知道这一点;对于垃圾回收器而言,elements 数组中的所有对象引用都同等有效 。 只有程序员知道数组的非活动部分是不重要的 。 程序员可以把这个情况告知垃圾回收器,做法很简单:一旦数组元素变成了非活动部分的一部分,程序员就手工清空这些数组元素 。

        一般来说 ,只要类是自己管理内存,程序员就应该警惕内存泄漏问题 。 一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空 。

        内存泄漏的另一个常见来源是缓存 。 一旦你把对象引用放到缓存中,它就很容易被遗忘掉,从而使得它不再有用之后很长一段时间内仍然留在缓存中 。 对于这个问题,有几种可能的解决方案 。 如果你正好要实现这样的缓存:只要在缓存之外存在对某个项的键的引用,该项就有意义,那么就可以用 WeakHashMap 代表缓存;当缓存中的项过期之后,它们就会自动被删除 。 记住只有当所要的缓存项的生命周期是由该键的外部引用而不是由值决定时,WeakHashMap 才有用处。

        更为常见的情形则是,“缓存项的生命周期是否有意义”并不是很容易确定,随着时间的推移,其中的项会变得越来越没有价值 。 在这种情况下,缓存应该时不时地清除掉没用的项 。 这项清除工作可以由一个后台线程( 可能是 ScheduledThreadPoolExecutor )来完成,或者也可以在给缓存添加新条目的时候顺便进行清理 。LinkedHashMap 类利用它的 removeEldestEntry 方法可以很容易地实现后一种方案 。 对于更加复杂的缓存,必须直接使用 java.lang.ref 。

        内存泄漏的第三个常见来源是监听器和其他回调 。 如果你实现了一个 API,客户端在这个 API 中注册回调,却没有显式地取消注册,那么除非你采取某些动作,否则它们就会不断地堆积起来 。 确保回调立即被当作垃圾回收的最佳方法是只保存它们的弱引用( weak reference ) ,例如,只将它们保存成 WeakHashMap 中的键 。

        由于内存泄漏通常不会表现成明显的失败,所以它们可以在一个系统中存在很多年 。往往只有通过仔细检查代码,或者借助于 Heap 剖析工具( Heap Profiler )才能发现内存泄漏问题 。 因此,如果能够在内存泄漏发生之前就知道如何预测此类问题,并阻止它们发生,那是最好不过的了。

多思计算机组成原理实验:模型机课程设计 计算机组成原理实验教程 基于多思网络虚拟实验系统 张雯雰 阅读详情

相关推荐

使用HFSS仿真分支波导耦合器

本文介绍了分支波导耦合器的HFSS仿真设计过程。首先给出了器件关键参数(t=0.365mm,l=1.600mm等),详细说明了建模步骤:包括创建中心分支、设置变量参数、镜像复制两侧分支、矩形波导端口设计等操作。重点阐述了激励端口设置方法,包括四个端口的积分线绘制,以及求解频率设定。最后展示了S参数、幅度平衡度和相位差等关键性能指标的仿真结果提取方法。整个设计过程体现了HFSS在微波器件仿真中的参数化建模和结果分析能力。

shao666888的博客 180

消除过期对象的引用

为什么要手动消除过期对象的引用 虽然JDK自带垃圾回收机制会自动回收不再使用的对象,但是JDK的垃圾回收机制并没有那么智能,仍会存在“内存泄漏”问题,例如下面的例子: import java.util.Arrays; import java.util.EmptyStackException; public class Stack { private Object[] elements; pr...

weixin_42522453的博客 306

内网Linux服务器离线安装python包

3、将下载的依赖包和requirements.txt 拷贝到内网主机,依赖包和requirements.txt放同一级目录,进入该目录,运行指令。其实还有个更加方便的办法,联网主机装个与内网主机一样环境的虚拟机,在虚拟机中下载py包,拷贝到内网主机后就能直接安装了,省去手动下载py包的步骤。简单记录下最近遇到的一个小问题,内网主机没有内网源,处于无互联网状态,安装python包只能通过联网主机下载好后拷贝到内网主机。由于内网主机安装了多个版本的python,为了防止搞错,使用这种方式来调用pip安装。

cyc头发还挺多的博客 650

消除过期对象引用

首先本篇文章提到了内存泄漏。是指一些被实例化出后的对象不再被使用但是并没有被JVM中的垃圾回收机制回收。内存泄漏是发生在堆内存中的。内存泄漏发生的原因:1、类自己管理内存。对于一个栈,当栈顶指针下移elements[size++]=e,原栈顶元素被抛出后elements[--size],抛出的对象并没有显示,它还是存在于数组中原来的位置。只是指针不再指向它,他不再被调用 但是抛出的对象还是指向其他...

weixin_30408675的博客 173

ethercat linux lan9252 - lan9253调试

linux 的ethercat测试

linsheng_111的专栏 1934

20、微电网系统的系统框架、建模与控制架构解析

本文详细解析了微电网系统的系统框架、建模方法以及控制架构。文章首先介绍了在系统的系统(SoS)框架下,微电网如何通过微控制器(MC)和微电网中央控制器(MGCC)协调运行,并支持并网与孤岛模式下的高效能量管理。随后,针对微电网的关键组件,包括微涡轮机、光伏太阳能电池和风力涡轮机,提供了详细的数学建模分析。最后,探讨了微电网的控制架构设计,涵盖分层控制和共识控制策略,以实现系统的高效、稳定运行,满足日益增长的能源需求与市场要求。

elastic6hunter的博客 206

06.消除过期的对象引用

当程序员第一次被类似这样的问题困扰的时候,它们往往会过分小心:对于每一个对象的引用,一旦程序不再用到它,就把它清空。其实这样做即没必要,也不是我们所期望的,因为这样做会把程序代码弄得很乱。清空对象引用应该是一种例外,而不是一种规范行为。消除过期引用最好的方法是让包含该引用的变量结束其生命周期。如果你是在最紧凑的作用域范围内定义每一个变量(第57项),这种情形就会自然而然地发生。那么,何时应该清空引用呢?Stack类的哪方面特性使它易于遭受内存泄漏的影响呢?简而言之,问题在于,

DSDS454651的博客 554

扩散模型实战:从零开始训练手写数字生成模型

手写数字的数据集是绝大部分炼丹师的深度学习初恋,这篇博客以代码为主,手把手带读者搭建一个基于扩散模型的手写数字生成模型,非常适合刚接触扩散模型的初学者学习。

沉迷单车的追风少年 1914

消除过期的对象引用

内存泄漏通常不会表现的很明显,可以在系统中存在很多年,只有通过检查代码,或借助Heap剖析工具才能发现内存泄漏问题,所以要尽量在内存泄漏发生之前就知道如何预测此类问题。

北辰 669

12、多端神经形态晶体管:原理、应用与算法探索

本文综述了多端神经形态晶体管的原理、应用与算法探索。从神经元MOS晶体管的发展到基于电解质栅极晶体管(EGT)的新型器件设计,系统阐述了其在低电压、多功能逻辑运算和突触行为模拟方面的优势。重点介绍了其在化学生物传感器(如多巴胺和pH检测)中的高灵敏度应用,以及在树突整合、时空总和、动态逻辑和神经元算术等树突算法中的实现。文章还总结了该类器件在神经形态计算、智能传感等领域的广阔前景,并分析了当前面临的材料工艺、理论建模与系统集成挑战,展望了未来发展方向。

delta的博客 143

AI问数,智慧赋能:基于大语言模型的数据播报员应用实践探索

AI问数技术正在改变企业与数据交互的方式,它以自然语言为桥梁,让数据不再是少数专家的专利,而是成为所有业务人员的决策伙伴。这不仅是技术的创新,更是管理理念的革新。在数字化转型的关键阶段,企业应积极拥抱AI问数技术,通过降低数据使用门槛、提升数据利用效率、释放数据潜在价值,实现真正的数据驱动决策,为企业的高质量发展注入源源不断的智慧动能。AI问数,正在开启一个数据普惠的新时代。

getusushu的博客 64

【第7条】消除过期的对象引用

消除过期的对象引用 当你从手工管理内存的语言(比如C或C++)转换到具有垃圾收集功能的比如Java语言时,程序员的工作会变得更加容易,因为当你用完了对象之后,它们会被自动回收。当你第一次经历对象回收功能的时候,会觉得这简直有点不可思议。它很容易给你留下这样的印象,认为自己不再需要考虑内存管理的事情了,其实不然。 考虑以下简单的栈实现: // Can you spot the "memory leak"? public class Stack { private Object[] eleme.

qq_42765867的博客 446

ESD防护设计宝典(十一):CE(传导发射)超标问题排查与解决

(Conducted Emission, CE),亦称为传导骚扰,是电子电气设备或系统内部的电压、电流通过信号线、电源线或地线向外传输,对其他电子电气设备或系统造成电磁干扰的物理现象。其。

m0_56451176的博客 856

【Effective Java】第7条:消除过期的对象引用

通过合理使用弱引用数据结构、及时清理集合中的元素、取消注册不再需要的监听器和回调函数等技术手段,我们可以有效地遵循这一原则并编写出更高效、更可靠的Java程序。过期的对象引用是指那些不再需要但仍然被持有的对象引用,它们会阻止垃圾回收器回收这些对象,从而导致内存泄漏。如果集合中的元素不再被需要,但它们的引用仍然存在于集合中,那么这些元素就不会被垃圾回收器回收。当缓存中的数据不再需要时,应该及时清理这些数据的引用,以避免内存泄漏。中,键是弱引用的,当键不再被其他对象引用时,它们可以被垃圾回收器回收。

2401_86224057的博客 975

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

《Effective Java》第7条:消除过期的对象引用

那如果这段代码反复的执行非常多的添加(push)和删除(pop)操作,就会有大量的类似于 “student4(赵六)” 这样的无用对象占据内存,最终可能会导致内存泄露,虽然说这种可能性很小(尤其是现在各种硬件性能过剩的情况下,可能性会更小)。在上面的例子中,我们将 student4 的类型设置为Student,如果 student4 被保留了下来,那么其中的 String name 对象,int age 对象,都会被保留,因为它们也是被 student4 强引用的对象。尽快地检测出程序中的错误总是有益的。

TD_FAlmK的博客 643

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

《Effective Java》解读第7条:消除过期的对象引用

摘要: 本文探讨了Java中内存泄漏问题及其解决方案。尽管Java有自动垃圾回收机制,但程序若保留过期对象引用仍会导致内存泄漏。重点分析了三种典型场景:1)类自行管理内存时(如栈实现),需手动置null释放无效引用;2)缓存场景建议使用WeakHashMap或缓存库自动清理;3)监听器需显式注销或使用弱引用。核心建议包括:警惕自管理内存的类、谨慎使用null、优先采用成熟工具库,并通过代码审查和静态分析预防泄漏。开发者应培养引用管理意识,而非过度依赖GC。

Cosmoshhhyyy的博客 710

老版QQ原生表情gif动态

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

Effective Java -- 消除过期的对象引用

本文是 《Effective Java Second Edition》第6条的读书笔记,文中如有错误或表述不当,非常欢迎能批评指正,本人不胜感激!我们来用一段通俗易懂的话来描述什么是过期的对象引用 在我们的程序中,有一些对象我们程序员已经非常明确的知道其不会再被使用,由于还存在被引用(我们知道如果执行了这种引用就是非法操作),所以不会被GC(内存泄露),所以这种引用的额存在已经没有任何的价值,故我

未思 904

Effective Java笔记第一章创建和销毁对象第六节消除过期的对象引用

Effective Java笔记第一章创建和销毁对象 第六节消除过期的对象引用 1.如果一个栈先增长,然后收缩,那么从栈中弹出的对象将不会被当做垃圾回收,即使使用栈的程序不再引用这些对象,他们也不会被回收。应为栈内部维护着对这些对象的过期引用。过期引用是指永远也不会再被解除的引用。 public class Demo1 { private Object[] elements; private int size=0; private static final int DEFAULT_

zh123456_789的博客 247

Java:Effective java学习笔记之 消除过期对象引用

Java消除过期对象引用消除过期对象引用1、Java的垃圾回收机制2、Java中的内存泄露3、常见的内存泄露参考 消除过期对象引用 很多人可能在想这么一个问题:Java有垃圾回收机制,那么还存在内存泄露吗?答案是肯定的,所谓的垃圾回收GC会自动管理内存的回收,而不需要程序员每次都手动释放内存,但是如果存在大量的临时对象在不需要使用时并没有取消对它们的引用,就会吞噬掉大量的内存,很快就会造成内存溢出。 1、Java的垃圾回收机制 Java中的对象是在堆中分配,对象的创建有2中方式:new或者反射。对象的回收是

JMW1407的博客 871

Effective Java 2.6——消除过期的对象引用

第六条 消除过期的对象引用java与C++最大的不同或许就是在于java有自己的垃圾回收机制(对象的创建销毁都是由java虚拟机管理的),而C++所有对象的创建清理都是由程序员自己动手管理的。对java虚拟机方面的知识感兴趣的童鞋们可以去看看我写的另一系列文章《深入理解java虚拟机》学习笔记。

秋千不会坠的博客 311

Effective Java 消除过期的对象引用学习记录

通过及时置空引用、弱引用或软引用以及实施缓存过期略,我们可以消除过期的对象引用,有效地内存。在Java中,当对象不再被使用时,希望垃圾回收机制能够及时回收这对象的内存。这种情况常称为过期的对象引用。过期的对象引可能导致内存泄漏,即程序仍然占用着再需要的内存,而这些内存无法被垃回收。通过本文的介绍,您应该对如何消过期的对象引用有了更深入的理解,并运用这些技巧来优化和提高您的Java。了消除过期的对象引用,我们需要及时清不再需要的对象引用。变所引用的对象在不再需要时,没有被垃圾收机制回收,从而产生内存泄漏。

weixin_36639192的博客 405

Effective Java 【创建和销毁对象篇】第7条 消除过期的对象引用

避免创建不必要的对象 Java具有垃圾回收机制,当用完对象以后,会被自己回收,但是并不代表就不需要考虑内存管理的事情。 请看下面的例子: public class Stack { public int size = 0; private Object[] elements; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Objec

zhangxiaoxiao9527的博客 251

《Effective Java》阅读笔记6 消除过期的对象引用

1.序 如果有同学接触过C/C++,应该会对内存空间的回收有着深刻的印象。举一个典型的例子——删除C语言链表。 void deleteList(list l){ position p, temp;​ p = l->next; l->next = NULL; while(p != NULL) { temp = p->next; free(p); // 释放掉结点占用的内存空间 p = te

weixin_41563161的博客 274

Effective Java-6:消除过期的对象引用

1、内存泄露的常见来源 1.1 过期引用 class MyStack { private Object[] elements; private int size=0; private static final int DEFAULT_INITAL_CAPACITY=16; public MyStack(){ elements=new Object[DEFAULT_INITAL_CAPACITY]; } public void push(Obje

Yisnow.的博客 212

《Effective Java》第6条:消除过期的对象引用

原文地址: https://itweknow.cn/detail?id=68 ,欢迎大家访问。 说到Java,大概很多人都知道GC。Java有自动的垃圾回收机制,当然了,在这篇文章里面就不去深究GC的具体实现了。那么以后了垃圾自动回收,我们是不是就在也不用担心内存泄露的问题了呢。这种问题的答案一般来讲都是否定的。那么这篇文章我们就一起来跟着《Effective Java》来了解一下这个问题。 ...

playing_the_fool的博客 359

Effective java 笔记 ---- 第七条 消除过期的对象引用

1. 例子代码: 不严格的讲,这段程序有一个“内存泄漏”,随着垃圾回收器活动的增加,或者由于内存占用的不断鞥见,程序性能的降低会逐渐表现出来。在极端情况下,这种内存泄漏会导致磁盘交换,甚至导致程序失败(OutOfMemoryError错误)。 程序中哪里发生了内存泄漏呢?如果一个栈先是增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收,即使使用栈的程序不再引用这些对象,它们也...

huanhuan8944172的专栏 249
上一篇: Effective Java笔记(6)避免创建不必要的对象
下一篇: Effective Java笔记(8)避免使用终结方法和清除方法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值