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

Java提高——Java的内存回收(1) Java引用的种类 当程序员通过new关键字创建对象,即视为为Java对象申请内存空间。JVM会在堆内存中为每个对象分配空间;当一个对象失去引用的时候,JVM垃圾回收机制会自动清除他们,并回收他们所占用的内存空间。 Java内存管理包括内存分配(创建Java对象的时候)和内存回收(回收 Java对象的时候)两个方面。 JVM垃圾回收机制是否回收一个对象的标准:是否有引用变量引用该对象?  ... 阅读详情

 阿堂在介绍“强引用,软引用,弱引用,虚引用”之前,前面没有对内存泄露的概念进行说明,这里简单补充说明一下.
  内存泄露:程序运行过程中,会不断分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,这就是内存泄漏.
(1)强引用
  这是java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是强引用.java程序可通过强引用来访问实际的对象。当一个对象被一个或一个以上的强引用变量引用时,它处于可达状态,它不可能被系统垃圾回收机制回收。
  强引用是Java编程中广泛使用的引用类型,被强引用所引用的Java对象绝不会被垃圾回收机制回收,即使系统内存紧张;即使有些Java对象以后永远也不会被用到,JVM也不会回收被强引用所引用的Java对象.
  由于JVM肯定不会回收强引用所引用的JAVA对象,因此强引用是造成JAVA内存泄漏的主要原因。
    如 ReceiptBean rb=new ReceiptBean(); rb就代表了一种强引用的方式
(2)软引用
  软引用需要通过SoftReference类来实现,当一个对象只具有软引用时,它可能被垃圾回收机制回收。对于只有软引用的对象而言,当系统内存空间足够时,它不会被系统回收,程序也可以使用该对象;当系统内存空间不足时,系统将回收它.
  软引用通常用在对内存敏感的程序中, 软引用是强引用很好的替代。对于软引用,当系统内存空间充足时,软引用与强引用没有太大的区别,当系统内存空间不足时,被软引用所引用的JAVA对象可以被垃圾回收机制回收,从而避免系统内存不足的异常.
  当程序需要大量创建某个类的新对象,而且有可能重新访问已创建老对象时,可以充分使用软引用来解决内存紧张的问题。
例如 需要访问1000个Person对象,可以有两种方式
方法一 依次创建1000个对象,但只有一个Person引用指向最后一个Person对象
方法二 定义一个长度为1000个的Person数组,每个数组元素引用一个Person对象.

对于方法一,弱点很明显,程序不允许需要重新访问前面创建的Person对象,即使这个对象所占的空间还没有被回收。但已经失去了这个对象的引用,因此也不得不重新创建一个新的Person对象(重新分配内存),而那个已有的Person对象(完整的,正确的,可用的)则只能等待垃圾回收
对于方法二,优势是可以随时重新访问前面创建的每个Person对象,但弱点也有,如果系统堆内存空间紧张,而1000个Person对象都被强引用引着,垃圾回收机制也不可能回收它们的堆内存空间,系统性能将变成非常差,甚至因此内存不足导致程序中止。

  如果用软引用则是一种较好的方案,当堆内存空间足够时,垃圾回收机制不会回收Person对象,可以随时重新访问一个已有的Person对象,这和普通的强引用没有任何区别。但当heap堆内存空间不足时,系统也可以回收软引用引用的Person对象,从而提高程序运行性能,避免垃圾回收.

  例如.下面程序创建一个SoftReference数组,通过SoftReference数组来保存100个对象,当系统内存充足时,SoftRference引用和强引用并没在太大的区别

class Person
{
 String name;
 int age;
 public Person(String name , int age)
 {
  this.name = name;
  this.age = age;
 }
 public String toString()
 {
  return "Person[name=" + name
   + ", age=" + age + "]";
 }
}
public class SoftReferenceTest
{
 public static void main(String[] args)
  throws Exception
 {
  SoftReference<Person>[] people =
   new SoftReference[100];
  for (int i = 0 ; i < people.length ; i++)
  {
   people[i] = new SoftReference<Person>(new Person(
    "名字" + i , (i + 1) * 4 % 100));
  }
  System.out.println(people[2].get());
  System.out.println(people[4].get());
  //通知系统进行垃圾回收
  System.gc();
  System.runFinalization();
  //垃圾回收机制运行之后,SoftReference数组里的元素保持不变
  System.out.println(people[2].get());
  System.out.println(people[4].get());
 }
}


  上面程序创建了一个长度为100的SoftReference数组,程序使用这个数组来保存100个Person对象,当系统内存足够时,如下面图示,即使系统进行垃圾回收,垃圾回收机制也不会回收这些Person对象所占用的内存空间。这种情况下,SoftReference引用的作用与普通强引用效果完成一样。

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


 如果将上面的SoftReference数组的长度改为100000,将修改运行上面的程序的命令如下
 效果如下

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


   从上图如可以看出,当使用java -Xmx2m -Xms2m SoftReferenceTest命令强制堆内存只有2m,而且程序创建一个长度为100000的数组,这样使得系统内存紧张。在这种情况下,软引用所引用的Java对象将会被垃圾回收。

 下面,我们再来对比一下强引用的程序,将上面程序修改如下
public class StrongReferenceTest
{
 public static void main(String[] args)
  throws Exception
 {
  Person[] people =
   new Person[100000];
  for (int i = 0 ; i < people.length ; i++)
  {
   people[i] = new Person(
    "名字" + i , (i + 1) * 4 % 100);
  }
  System.out.println(people[2]);
  System.out.println(people[4]);
  //通知系统进行垃圾回收
  System.gc();
  System.runFinalization();
  //StrongReference数组里不受任何影响
  System.out.println(people[2]);
  System.out.println(people[4]);
 }
}

  上面程序以传统方式创建了一个Person数组,该数组长度为100000,即程序的堆内存将保存100000个Person对象,这将使得程序因为系统内存不足而中止。运行上面程序,看到如下所示的错务(强引用导致的内存不足)

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


  从上图不难看出,当程序使用强引用时,无论系统堆内存如何紧张,JVM垃圾回收机制都不会回收被强引用所引用的Java对象,因此最后导致程序因内存不足而中止。但如果把强引用改为软引用,就完成可以避免这种情况,这就是软引用的优势所在.

原文出处:http://zhang8mss.blog.163.com/blog/static/1104637562010424946050/

【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高级进阶学习-Java的内存回收(2)

  内存泄露:程序运行过程中,会不断分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,这就是内存泄漏.(1)强引用  这是java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量(变量指向对象所占空间地址的首地址--转者注),这个引用变量就是强引用.java程序可通过强引用来访问实际的对象。当一个对象被一...

CoderRobin的专栏 164

WSL中使用VMD图形化界面

【代码】WSL中使用VMD图形化界面。

handsome213的博客 840

【mybatis】mybatis一条sql更新两张数据表,mybatis关联更新多张数据表

示例sql: <update id="receipt" parameterType="com.pisen.cloud.luna.ms.security.code.base.mapper.beans.ReceiptBean"> update security_code_info info LEFT JO...

weixin_30505751的博客 4127

OSGEarth三维可视化避坑指南:如何高效加载SHP/TIF地理数据?

本文详细介绍了OSGEarth在三维地球可视化中高效加载SHP/TIF地理数据的实战策略,包括空间参考系配置、性能优化、二三维联动等关键技巧。通过具体案例和代码示例,帮助开发者解决坐标偏移、性能卡顿等常见问题,提升三维GIS开发效率。

weixin_29216957的博客 222

别再手动续期SSL证书了!用acme.sh配合阿里云DNS API,实现全自动HTTPS证书管理

本文详细介绍了如何使用acme.sh配合阿里云DNS API实现SSL/TLS证书的全自动管理,彻底解决手动续期带来的风险与不便。通过自动化部署流程,包括环境准备、API集成、多域名证书申请等关键步骤,帮助运维人员构建高效、可靠的HTTPS证书管理体系,显著提升安全性和运维效率。

weixin_29200485的博客 269

精选(49) 一个Java对象到底占用多大内存?

最近在调研MAT和VisualVM源码实现,遇到一个可疑问题,两者计算出来的对象大小不一致,才有了这样疑惑。 一个Java对象到底占用多大内存? 为了复现这个问题,准备了4个最简单类: class AAAAA {} class BBBBB { int a = 1;} class CCCCC { long a = 1L;} class DDDDD { String s = "hel...

cowbin2012的专栏 1万+

5分钟搞定!用FunASR在本地快速部署达摩院Paraformer语音识别模型

本文提供了一份快速部署指南,教你如何在5分钟内利用FunASR工具包在本地电脑上启动达摩院Paraformer语音识别模型。Paraformer作为一款非自回归端到端模型,以其推理速度快、识别精度高的特点,结合FunASR的一键式模型加载和统一API,让开发者能轻松构建本地语音识别系统,极大降低了前沿AI技术的应用门槛。

q9w8e7r6t5的博客 605

new一个Object对象占用多少内存?

Java的自动内存管理机制省却了很多编码工作,大大地提高了Java的生产力,而且JVM的性能也越来越好,特别是G1的出现,改善了垃圾回收中stop the world的状况。 也许很多人都没有考虑过这个问题,new一个Object对象到底占用多少内存呢( Object obj = new Object() )? 这里很明确的是obj是一个指向对象的引用,引用的长...

810364804 1583

Unity半透明物体景深失效?教你用双材质球方案完美解决(附完整Shader代码)

本文深入剖析了Unity中半透明物体导致景深效果失效的根本原因,即半透明物体默认不写入摄像机深度图。针对此问题,文章详细介绍了稳定高效的“双材质球”解决方案,通过为物体附加一个仅写入深度信息的不可见材质,完美修复景深效果,并提供了完整的Shader代码与实现脚本。

weixin_29010003的博客 381

别再让步进电机‘发烧’了!用FOC闭环驱动实现精准力矩控制(基于P0斩波恒流版)

本文详细介绍了如何利用FOC闭环驱动技术(基于P0斩波恒流版)解决步进电机过热和力矩控制不精准的问题。通过对比传统开环控制的缺陷,展示了FOC在降低温度、提升精度和能效方面的显著优势,并提供了硬件配置、软件实现及性能优化的完整方案。

weixin_30872157的博客 567

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

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

AI天才研究院 979

推荐11个顶级的Claude Code Skills

ClaudeCode的Skills系统为程序员提供了11个强大的AI辅助工具,包括代码审查、重构建议、单元测试生成、API文档自动生成、性能分析、安全扫描、数据库迁移脚本生成、CI/CD配置、依赖管理、ER图生成和日志分析等功能。这些"技能包"可大幅提升开发效率,从代码质量到协作沟通全方位优化工作流程。用户可根据需求选择2-3个核心功能开始尝试,熟练后还可自定义Skills。该系统需要配合Anthropic的API使用,建议先在小型项目测试再应用于核心业务。

分享AI、区块链技术及应用,未来已来 1852

java 内存 回收_java内存回收

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

weixin_26878995的博客 2300

基于多传感器融合的智身四足机器狗楼梯环境SLAM系统设计与实现

本文设计了一种基于多传感器融合的四足机器狗楼梯环境SLAM系统。系统采用Jetson Orin NX为主控制器,集成RealSense D435i深度相机和Livox Mid360激光雷达,在ROS2框架下实现平面定位精度<5cm、楼梯环境下导航不漂移的目标。通过多层次传感器融合策略、运动学约束优化和状态切换机制,解决了楼梯环境下的定位累积误差问题,实现了平面与楼梯环境的自动识别切换及精度复位功能。硬件设计注重传感器布局优化和精确标定,软件架构采用分层设计,确保实时性能。该系统为四足机器人在复杂地形中

huanghm88的专栏 241

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

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

tanmoney的博客 2124

温度PID控制PLC程序

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

Java内存回收机制

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

hequnwang10的博客 6330

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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

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

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

Java 内存分配和回收

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

m0_69529796的博客 628

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

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

m0_70081047的博客 323

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

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

FlywindMouse的专栏 1144

java 数组回收_java的内存回收

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

weixin_39828331的博客 876

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

下面几遍文章中,阿堂想和朋友们一起来探讨一个java中内存管理方面的一些细节和常见内存管理的小技巧。由于,java中本身已经提供了垃圾回收机制,并且这个是由JVM来自动执行的,也就是说,当一个java对象失去引用时,JVM的垃圾回收机制会自动清理它们,并回收它们所占用的内存空间。正因为此,所以一般的java程序员,就完全相信了java承诺的垃圾回收的说法了,这样就导致了java的内存泄露更隐蔽。。

FlywindMouse的专栏 1307

容器java堆内存什么时候回收_Java 堆外内存回收原理

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

weixin_35949153的博客 599

Java进阶 JVM 内存与垃圾回收篇

JVM 1. 引言 1.1 什么是JVM? 定义 Java Vritual Machine - java 程序的运行环境(Java二进制字节码的运行环境) 好处 一次编译 ,到处运行 自动内存管理,垃圾回收功能 数据下标越界越界检查 多态 比较 Jvm vs Jre vs JDK 1.2 学习路线 本文主要讲解的是HotSpot VM HotSpot VM 是目前市面上高性能虚拟机的代表作之一,采用解释器与即时编译器并存的架构 学习主要分为三个部分 此文为第一篇 内存与

weixin_68320784的博客 627
上一篇: win8启动黑屏解决
下一篇: Java高级进阶学习-Java的内存回收(3)
浪里一淘
博客等级 码龄15年 19粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值