Java中的垃圾回收与对象生命周期

转载自   Java中的垃圾回收与对象生命周期

1. 垃圾回收 

   垃圾回收是Java程序设计中内存管理的核心概念,JVM的内存管理机制被称为垃圾回收机制。 

  一个对象创建后被放置在JVM的堆内存中,当永远不再引用这个对象时,它将被JVM在堆内存中回收。被创建的对象不能再生,同时也没有办法通过程序语句释放它们。即当对象在JVM运行空间中无法通过根集合到达(找到)时,这个对象被称为垃圾对象。根集合是由类中的静态引用域与本地引用域组成的。JVM通过根集合索引对象。 

    在做Java应用开发时经常会用到由JVM管理的两种类型的内存:堆内存和栈内存。简单来讲,堆内存主要用来存储程序在运行时创建或实例化的对象与变量。例如通过new关键字创建的对象。而栈内存则是用来存储程序代码中声明为静态或非静态的方法。
 

(1) 堆内存 

    堆内存在JVM启动的时候被创建,堆内存中所存储的对象可以被JVM自动回收,不能通过其他外部手段回收,也就是说开发人员无法通过添加相关代码的手段来回收堆内存中的对象。堆内存通常情况下被分为两个区域:新对象区域与老对象区域。 

    新对象区域:又可细分为三个小区域:伊甸园区域、From区域与To区域。伊甸园区域用来保存新创建的对象,它就像一个堆栈,新的对象被创建,就像指向该栈的指针在增长一样,当伊甸园区域中的对象满了之后,JVM系统将要做到可达性测试,主要任务是检测有哪些对象由根集合出发是不可达的,这些对象就可以被JVM回收,并且将所有的活动对象从伊甸园区域拷贝到To区域,此时一些对象将发生状态交换,有的对象就从To区域被转移到From区域,此时From区域就有了对象。上面对象迁移的整个过程,都是由JVM控制完成的。 

    老对象区域:在老对象区域中的对象仍然会有一个较长的生命周期,大多数的JVM系统垃圾对象,都是源于"短命"对象,经过一段时间后,被转入老对象区域的对象,就变成了垃圾对象。此时,它们都被打上相应的标记,JVM系统将会自动回收这些垃圾对象,建议不要频繁地强制系统作垃圾回收,这是因为JVM会利用有限的系统资源,优先完成垃圾回收工作,导致应用无法快速地响应来自用户端的请求,这样会影响系统的整体性能。
 

(2) 栈内存 

    堆内存主要用来存储程序在运行时创建或实例化的对象与变量。例如通过new关键字创建的对象。而栈内存则是用来存储程序代码中声明为静态或非静态的方法。 

2. JVM中对象的生命周期 

   在JVM运行空间中,对象的整个生命周期大致可以分为7个阶段: 
   创建阶段; 
   应用阶段; 
   不可视阶段; 
   不可到达阶段; 
   可收集阶段; 
   终结阶段; 
   释放阶段
  

   上面这7个阶段,构成了JVM中对象的完整的生命周期。 


   (1) 创建阶段 

       在对象的创建阶段,系统主要通过下面的步骤,完成对象的创建过程: 
     
       <1> 为对象分配存储空间; 
       <2> 开始构造对象; 
       <3> 从超类到子类对static成员进行初始化; 
       <4> 超类成员变量按顺序初始化,递归调用超类的构造方法; 
       <5> 子类成员变量按顺序初始化,子类构造方法调用。 

       在创建对象时应注意几个关键应用规则: 
       
       <1> 避免在循环体中创建对象,即使该对象占用内存空间不大。 
       <2> 尽量及时使对象符合垃圾回收标准。比如 myObject = null。 
       <3> 不要采用过深的继承层次。 
       <4> 访问本地变量优于访问类中的变量。

 (2) 应用阶段 

       在对象的引用阶段,对象具备如下特征: 

      <1> 系统至少维护着对象的一个强引用(Strong Reference); 
      <2> 所有对该对象的引用全部是强引用(除非我们显示地适用了:软引用(Soft Reference)、弱引用(Weak Reference)或虚引用(Phantom Reference)).
 

      强引用(Strong Reference):是指JVM内存管理器从根引用集合出发遍历堆中所有到达对象的路径。当到达某对象的任意路径都不含有引用对象时,这个对象的引用就被称为强引用。 

       软引用(Soft Reference):软引用的主要特点是有较强的引用功能。只有当内存不够的时候,才回收这类内存,因此内存足够时它们通常不被回收。另外这些引用对象还能保证在Java抛出OutOfMemory异常之前,被设置为null。它可以用于实现一些常用资源的缓存,实现Cache功能,保证最大限度地使用内存你而不引起OutOfMemory。

 下面是软引用的实现代码:

 

import java.lang.ref.SoftReference;...A a = new A();...// 使用a...// 使用完了a, 将它设置为soft引用类型,并且释放强引用SoftReference sr = new SoftReference(a);a = null;...// 下次使用时if (sr != null) {a = sr.get();} else {// GC由于低内存,已释放a,因此需要重新装载a = new A();sr = new SoftReference(a);}

 软引用技术的引进使Java应用可以更好地管理内存,稳定系统,防止系统内存溢出,避免系统崩溃。因此在处理一些占用内存较大且生命周期较长,但使用并不繁地对象时应尽量应用该技术。提高系统稳定性。 
             
                                      
       弱引用(Weak Reference):弱应用对象与软引用对象的最大不同就在于:GC在进行垃圾回收时,需要通过算法检查是否回收Soft引用对象,而对于Weak引用,GC总是进行回收。Weak引用对象更容易、更快地被GC回收。Weak引用对象常常用于Map结构中。

import java.lang.ref.WeakReference;   ...                             A a = new A();   ...   // 使用a   ...   // 使用完了a, 将它设置为Weak引用类型,并且释放强引用   WeakReference wr = new WeakReference(a);   a = null;   ...   // 下次使用时   if (wr != null) {   a = wr.get();   } else {   a = new A();   wr = new WeakReference(a);   } 

 虚引用(Phantom Reference): 虚引用的用途较少,主要用于辅助finalize函数的使用。 

虚引用(Phantom Reference)对象指一些执行完了finalize函数,并为不可达对象,但是还没有被GC回收的对象。这种对象可以辅助finalize进行一些后期的回收工作,我们通过覆盖了Refernce的clear()方法,增强资源回收机制的灵活性。 

       
       在实际程序设计中一般很少使用弱引用和虚引用,是用软引用的情况较多,因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生。 


    (3) 不可视阶段 
         当一个对象处于不可视阶段,说明我们在其他区域的代码中已经不可以在引用它,其强引用已经消失,例如,本地变量超出了其可视 

的范围。 

try {   Object localObj = new Object();   localObj.doSomething();   } catch (Exception e) {   e.printStackTrace();   }   if (true) {   // 此区域中localObj 对象已经不可视了, 编译器会报错。   localObj.doSomething();   }  

 (4) 不可到达阶段 
       处于不可达阶段的对象在虚拟机的对象引用根集合中再也找不到直接或间接地强引用,这些对象一般是所有线程栈中的临时变量。所有已经装载的静态变量或者是对本地代码接口的引用。 


   (5) 可收集阶段、终结阶段与释放阶段
 
       当一个对象处于可收集阶段、终结阶段与释放阶段时,该对象有如下三种情况: 

       <1> 回收器发现该对象已经不可达。 

       <2> finalize方法已经被执行。 

       <3> 对象空间已被重用。 



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

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

相关文章

页面复杂对象传递参数 开发中遇到的问题

左边是我发送的数据 转换成右边的就可以接受到数据了 我发送的数据接收回来 这样发送 服务器就可以接收到数据了

hibernate正向生成数据库表以及配置——hibernate.cfg.xml

<?xml version1.0 encodingUTF-8?> <!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><!-- Generated by MyEclipse H…

蓝桥杯JAVA省赛2013-----B------4(黄金连分数)

【答案】&#xff1a;0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375 识别问题 --> 斐波那契的第n项与第n1项的比值n要多少才够 --> 精度处理大整数、大浮点数 &#xff1a;add()-&#xff1a;subtract()*&…

.NET仓储模式高级用例

主要结论 如果需要执行基本CURD之外的其他操作&#xff0c;此时就有必要使用仓储&#xff08;Repository&#xff09;。为了促进测试工作并改善可靠性&#xff0c;应将仓储视作可重复使用的库&#xff08;Library&#xff09;。将安全和审计功能放入仓储中可减少Bug并简化应用程…

可视化大屏设计尺寸_可视化大屏设计_酷炫不是最高效的大屏展示的唯一标准...

目前市面上有众多做大屏的可视化BI工具&#xff0c;有的部分企业为了要实现其功能效果而令人感到枯燥乏味&#xff0c;或者是为了看上去绚丽多彩而显得极端复杂&#xff0c;从而实现对于相当复杂而又冗余数据的深入分析&#xff0c;让企业决策者难以理解数据的价值。这也导致了…

Java的GC机制及算法

转载自 Java的GC机制及算法 GC的阶段 对每个对象而言&#xff0c;垃圾回收分为两个阶段&#xff1a;finalization和reclamation。 finalization: 指运行这个对象的finalize的方法。reclamation: 回收被这个对象使用的内存。 GC的过程的基本步骤首先确认对象是不可达的&#…

19年8月 字母哥 第一章 spring boot 2.x基础及概念入门 这里全部看完了 热部署没出来 第二章在前面2页 用热点公司网不行

http://springboot.zimug.com/1233100 文档 http://www.zimug.com/page/5 字母哥个人博客 11111 第一章 spring boot 2.x基础及概念入门 1.1.spring boot 产生的背景及其优势 1.2.spring boot 2.x 新特性说明 1.3.helloworld及项目结构介绍 1.4.IDEA结合spring b…

dell 恢复介质_戴尔官方WIN10恢复介质镜像下载与安装教程 | Dell 中国

前提&#xff1a;准备一个8G以上的空U盘相关视频请点击如何制作并使用win10 USB安装镜像目录:一、制作U盘安装介质1.打开链接&#xff0c;点击"下载OS Recovery Tool"&#xff0c;2.运行下载好的 OS Recovery Tool &#xff0c;点击INSTALL&#xff0c;3.安装完成&am…

CSS3(笔记)

CSS简介 CSS是什么 Cascading Style Sheet层叠样式表 CSS&#xff1a;表现&#xff08;美化网页&#xff09; 字体&#xff0c;颜色&#xff0c;边距&#xff0c;高度&#xff0c;宽度&#xff0c;背景图片&#xff0c;网页定位&#xff0c;网页浮动 CSS怎么用&#xff08;快…

19年8月 字母哥 第三章 spring boot 配置原理实战 用热点公司网不行

第三章 spring boot 配置原理实战 3.1.结合配置加载讲解bean自动装配原理 3.2.详解YAML语法及占位符语法 3.3.获取自定义配置的两种实现方法 3.4.配置文件注入值数据校验 3.5.加载旧项目配置文件的两种方式 这节课就是适配老的项目而已所以要新建分支 因为不是很常用 3.6.profi…

.NET Core跨平台图形处理库ImageSharp

ImageSharp 是支持.NET Core跨平台图形处理库&#xff0c;ImageSharp是ImageProcessor 的.NET Core跨平台实现。 ImageSharp 支持如下操作&#xff1a; 调整大小&#xff0c;裁剪&#xff0c;翻转&#xff0c;旋转&#xff0c;边缘检测等。 支持BMP&#xff0c;PNG&#xff0c;…

JVM GC参数以及GC算法的应用

转载自 JVM GC参数以及GC算法的应用1. 串行收集器 串行收集器是最古老&#xff0c;最稳定以及效率高的收集器可能会产生较长的停顿&#xff0c;只使用一个线程去回收-XX:UseSerialGC新生代、老年代使用串行回收新生代复制算法老年代标记-压缩串行收集器的日志输出&#xff1a…

hibernate正向生成数据库表以及配置——Student.java

package cn.bdqn.studentInfo.entity;import java.util.HashSet; import java.util.Set;/*** 学生表的实体类* author Administrator**/ public class Student {private Integer id;private String name;private Set<Teacher>teachersnew HashSet<Teacher>();publi…

全局配置_配置全局异常处理,结果没有想到,spring boot实践(3)

01 spring boot读取配置信息02 多环境配置这个功能详细大家在项目中也经常遇到&#xff0c;通常我们在写controller的时候会定义一个全局的异常处理。任何的controller出现异常都会进入到这个全局异常统一抛出&#xff0c;同时我们也可以定义一个自定义的异常类来处理一些特殊的…

蓝桥杯JAVA省赛2013-----B------5(有理数类)

五、有理数类 【答案】&#xff1a;Rational(this.rax.rb this.rbx.ra, this.rb*x.rb) public class Test01 {static class Rational //内部类 【main调用内部类 &#xff1a; 内部类前 要加 static】{private long ra;private long rb;private long gcd(long a, long b…

19年8月 字母哥 第四章 常用web开发数据库框架 不要用公司网络加载不出来 用热点!!!

第四章 常用web开发数据库框架 4.1.整合Spring JDBC操作数据 4.2 Spring JDBC多数据源的实现 4.3.Spring JDBC JTA实现分布式事务 4.4.ORM主流框架选型 4.5.bean转换Dozer的快速上手 4.6.整合Spring Data JPA操作数据 4.7.Sp…

分库分表的几种常见形式以及可能遇到的难

在谈论数据库架构和数据库优化的时候&#xff0c;我们经常会听到“分库分表”、“分片”、“Sharding”…这样的关键词。让人感到高兴的是&#xff0c;这些朋友所服务的公司业务量正在&#xff08;或者即将面临&#xff09;高速增长&#xff0c;技术方面也面临着一些挑战。让人…

JVM 调优和垃圾回收器说明

转载自 JVM 调优和垃圾回收器说明JVM垃圾收集算法JVM垃圾收集算法有四种&#xff1a;标记-清除算法、复制算法、标记-整理算法、分代收集算法标记-清除算法&#xff1a;该算法如同它的名字一样&#xff0c;分为两个阶段&#xff1a;标记、清除。首先标记出所有需要回收的对象…

python中的数组按顺序切片_python切片(获取一个子列表(数组))详解

切片&#xff1a;切片指从现有列表中&#xff0c;获取一个子列表返回一个新列表&#xff0c;不影响原列表。下标以 0 开始&#xff1a;list [红,绿,蓝,白,黑,黄,青]# 下标 0 1 2 3 4 5 6取单个值语法&#xff1a;列表[n]n为下标&#xff0c;n0表示第一个 &#xff0c; n1表示第…

.net core快速上手

2014年11月12日的Connect ();开发者活动上宣布将.NET堆栈基于MIT协议开源&#xff0c;并且提供开源保证&#xff0c;托管在Github上。当时的版本与最终目标相距甚远&#xff0c;然而有一点可以肯定的是&#xff0c;这是一个与.NET Framework 4.x完全不同的框架。 这在社区引发了…