finalize

CLR的垃圾回收机制 (一)

狂风中的少年 提交于 2019-12-01 17:20:01
CLR的垃圾回收机制 (一) 从这节开始就涉及CLR 最有意思的地方了,也是CLR 思想的核心部分,比较难理解,要反复思考才能有收获。这节是我对CLR的垃圾回收的整理,应用程序是如何构造新对象,托管堆如何控制这些对象的生存期,以及回收这些对象的内存。本节的内容主要还是参考CLR via C# 这本书,还有就是蒋金楠的博文。 我们先大致了解一下CLR 中的资源概念、以及资源的生存周期 CLR的垃圾回收机制用于清理废弃的资源,这些资源例如文件、网络连接、socket、数据库连接、内存等。在面向对象的环境中,每个类型都代表可供程序使用的一种资源。要使用这些资源,必须为代表资源的类型分配内存,以下是访问一个资源所需要的步骤。 1 调用IL 指令 newobj ,为代表资源的类型 分配内存 (一般使用C# new 操作符来完成)。 2 初始化内存 ,设置资源的初始状态并使资源可使用。类型的实例构造器负责设置初始化状态。 3 访问类型的成员来 使用资源。 4 摧毁资源 的状态以进行清理。 5 释放内存 。垃圾回收器独自负责这一步。 那应用程序是如何创建对象的呢?我们一步一步来解释这个问题 。C# 的new 操作符导致CLR 执行以下步骤。 1 计算类型的字段所需要的字节数。 2 加上对象的开销所需要的字节数。 每个对象都有两个开销字段:类型对象指针和同步块索引。32位应用程序,每个对象需要8

Why does the traditional Dispose pattern suppress finalize?

早过忘川 提交于 2019-12-01 15:49:19
Assuming this as the traditional Dispose pattern (taken from devx but seen on many websites) class Test : IDisposable { private bool isDisposed = false; ~Test() { Dispose(false); } protected void Dispose(bool disposing) { if (disposing) { // Code to dispose the managed resources of the class } // Code to dispose the un-managed resources of the class isDisposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } I don't understand why we call GC.SupressFinalize(this) . This requires me to write my own managed resource disposal, including nulling my references? I'm a

Why does the traditional Dispose pattern suppress finalize?

僤鯓⒐⒋嵵緔 提交于 2019-12-01 14:50:51
问题 Assuming this as the traditional Dispose pattern (taken from devx but seen on many websites) class Test : IDisposable { private bool isDisposed = false; ~Test() { Dispose(false); } protected void Dispose(bool disposing) { if (disposing) { // Code to dispose the managed resources of the class } // Code to dispose the un-managed resources of the class isDisposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } I don't understand why we call GC.SupressFinalize(this

Java垃圾回收与算法详解

♀尐吖头ヾ 提交于 2019-12-01 13:55:47
首先来张祖传的思维导图:   内存回收与垃圾收集器在很多时候都是影响系统性能、并发能力的主要因素,虚拟机之所以提供多种不同的收集器以及提供大量的调节参数,是因为只有根据实际应用需求、实现方式选择最优的垃圾收集方式才能获得最好的性能。 GC发生在那里:   JVM虚拟机运行时内存区域主要分为(如下图):虚拟机栈、本地方法栈、程序计数器、Java堆、方法区。其中虚拟机栈、本地方法栈、程序计数器为线程私有区域,在这几个区域中就不需要过多的考虑垃圾回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了。而Java堆和方法区则不一样,这两个区域为线程共享区域,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间时才能知道会创建那些对象,这两部分内存的分配和回收都是动态的,垃圾回收主要发生在这两部分区域。JVM内存区域解析可参考:xxxxxx 如何判断Java中那些对象需要被回收:   现在主流的虚拟机主要使用可达性分析算法来判断对象是否可以被回收,而不是使用引用计数算法来判断,并行进行二次标记筛选来最终回收对象。 1、引用计数算法:   基本思想:给对象中加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1;任何时刻计数器为0时对象就是不能被使用,可回收了。   例子:在发生gc时t1

优秀的Java程序员必须了解GC的工作原理

旧时模样 提交于 2019-12-01 10:04:43
一个优秀的 Java 程 序员必须了解GC的工作原理、如何优化GC的性能、如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统、实时系统等,只有全面 提升内存的管理效率 ,才能提高整个应用程序的性能。本篇文章首先简单介绍GC的工作原理之后,然后再对GC的几个关键问题进行深入探讨,最后提出一些 Java 程序设计建议,从GC角度提高Java程序的性能。   GC的基本原理   Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放。   对于程序员来说,分配对象使用new关键字;释放对象时,只要将对象所有引用赋值为null,让程序不能够再访问到这个对象,我们称该对象为\"不可达的\".GC将负责回收所有\"不可达\"对象的内存空间。   对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有 对象(详见 参考资料1 )。通过这种方式确定哪些对象是\"可达的\",哪些对象是\"不可达的\".当GC确定一些对象为\"不可达\"时,GC就有责任回收这些内存空间。但 是,为了保证GC能够在不同平台实现的问题,Java规范对GC的很多行为都没有进行严格的规定。例如,对于采用什么类型的回收算法、什么时候进行回收等 重要问题都没有明确的规定。因此

分析一套源代码的代码规范和风格并讨论如何改进优化代码

五迷三道 提交于 2019-12-01 06:58:06
下面分析一套跟我工程实践项目比较相关的java项目,银行收账转账结账系统。 1.结合工程实践选题相关的一套源代码,根据其编程语言或项目特点,分析其在源代码目录结构、文件名/类名/函数名/变量名等命名、接口定义规范和单元测试组织形式等方面的做法和特点; (1)源码目录结构: /src 源代码目录   /src/main 工程源代码目录     /src/main/java 工程java源代码目录     /src/main/resources 工程的资源目录(Mybatis、Spring等的配置文件)   /src/test 单元测试目录     /src/test/java 工程java单元测试目录,存放所有测试.java文件,如JUnit测试类 Maven Dependencies 引到项目的jar包 pom.xml maven最核心的配置文件,与构建过程相关的设置都在这个文件中配置 maven工程的目录结构均按此标准,实现项目的自动化构建。遵循 约定->配置->编码 的过程,可以进行配置的不需要专门编码指定,能按照实现约定好的规则处理的不需要再多余配置,能够减少多余劳动力,还能够预防低级错误。 (2)文件,接口,类,函数和变量等命名规范 文件命名采用全小写; 类和接口采用大写开头的驼峰命名方法; 函数和变量采用小写开头的驼峰命名方法。 (3)接口定义规范

[Java复习] JVM

空扰寡人 提交于 2019-12-01 05:40:24
Part1:Java类加载机制:类加载器,类加载机制,双亲委派模型 1. Java 类加载过程? 类加载过程 即是指JVM虚拟机把.class文件中类信息加载进内存,并进行解析生成对应的class对象的过程。 三阶段: 加载 - 链接 (验证 - 准备 - 解析) - 初始化 加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。 加载阶段 :(三件事) 1. 通过类名获取二进制字节流。 2. 将字节流的静态存储结构转化为方法区的运行时数据结构。 3.在堆中生成一个代表这个类的Class对象,作为方法区数据的访问入口。 链接阶段: 1. 验证:确保加载的类的正确性(文件格式验证,元数据验证,字节码验证,符号引用验证) 2.准备:为类的静态变量分配内存,并将其初始化为默认值 假设一个类变量的定义为: public static int value=1; 那么变量value在准备阶段过后的初始值为0,而不是1,因为这时候尚未开始执行任何Java方法。 而把value赋值为1的public static指令是在程序编译后,存放于类构造器 <clinit>()方法之中的,所以把value赋值为1的动作将在初始化阶段才会执行。 假设一个类变量的定义为: public

Java GC

女生的网名这么多〃 提交于 2019-12-01 02:34:05
1、在什么时候触发GC   GC分为① Minor GC(针对新生代的GC) ② Full GC(清理整个堆空间—包括年轻代和永久代)。 Minor GC 的触发条件是:大多数情况,新生对象在Eden区分配,当Eden区空间不足时就触发Minor GC。清除非存活对象,将存活对象放到幸存者区,然后整理幸存者的两个区。 Full GC触发条件是:①老年代空间不足②持久带空间不足③调用System.gc的时候④ GC担保失败 。   什么是 GC担保失败 GC担保失败就是一个空间分配的担保问题 每次调用Minor GC之前先判断老年代的最大可用连续空间是否大于新生代所有对象的总空间,如果大于就Minor GC,如果小于就查看配置是否允许担保失败,不允许就直接Full GC。如果允许担保失败,就判断老年代最大的可用连续空间是否大于历史平均晋升到老年代对象的大小,大于则Minor GC,小于则Full GC。 2、对什么东西清除 GC找寻什么对象会被回收是先通过可达性分析算法,从 GC Roots 开始往下找 引用节点 ,再找这个引用节点下面的引用节点,直到全部找完,其中没有引用的结点又叫无用结点,将会被标记为可回收对象,但可回收对象不表示他立即被回收,而是经过两次标记后才会被回收,第一次标记是看它有没有重写 finalize()方法 ,没有重写,则被第二次标记然后回收。否则

垃圾收集器与内存分配策略

◇◆丶佛笑我妖孽 提交于 2019-11-30 17:54:08
1、判断对象的存活   1、引用计数   原理:给一个对象添加一个引用计数器,每当一个地方引用它时,计数器就加1;当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可再被使用的;   优点:效率高;   缺点:很难解决对象间的循环引用;   2、可达性分析   原理:通过一系列称为“GC Roots”的对象作为起点向下开始搜索,搜索走过的路径称为引用链,当一个对象到“GC Roots”没有任何引用链时(不可达),则该对象是不可用的;   可作为“GC Roots”的对象:1、虚拟机栈中引用的对象;2、方法区中“静态属性、常量”引用的对象;3、本地方法中引用的对象;      3、各种引用   强引用   软引用:对于软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果第二次回收后还没有足够内存,才会抛出内存溢出异常;   弱引用:弱引用关联的对象,只能生存到下一次垃圾收集发生之前。下一次垃圾收集器工作时,无论当前内存是否足够,都会回收掉 只被 弱引用关联的对象;   虚引用:没有其他影响;为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。      4、至少两次标记才会宣告对象死亡   第一次标记:是否与“GC Root相连”以及是否有必要执行finalize方法;   第二次标记:在F

GC垃圾回收机制详解

浪尽此生 提交于 2019-11-30 13:23:28
JVM堆相关知识 为什么先说JVM堆? JVM的堆是Java对象的活动空间,程序中的类的对象从中分配空间,其存储着正在运行着的应用程序用到的所有对象。这些对象的建立方式就是那些new一类的操作,当对象无用后,是GC来负责这个无用的对象。 JVM堆 (1) 新域:存储所有新成生的对象 新域会被分为3个部分:1.第一个部分叫Eden。2.另两个部分称为辅助生存空间(幼儿园),我这里一个称为A空间(From sqace),一个称为B空间(To Space)。 (2) 旧域:新域中的对象,经过了一定次数的GC循环后,被移入旧域 (3)永久域:存储类和方法对象,从配置的角度看,这个域是独立的,不包括在JVM堆内。默认为4M。� 垃圾回收的原因 从计算机组成的角度来讲,所有的程序都是要驻留在内存中运行的。而内存是一个限制因素(大小)。除此之外,托管堆也有大小限制。因为地址空间和存储的限制因素,托管堆要通过垃圾回收机制,来维持它的正常运作,保证对象的分配,尽可能不造成“内存溢出”。 垃圾回收的基本原理 ( 算法思路都是一致的:把所有对象组成一个集合,或可以理解为树状结构,从树根开始找,只要可以找到的都是活动对象,如果找不到,这个对象就被回收了 ) 垃圾回收分为两个阶段: 标记 --> 压缩标记的过程,其实就是判断对象是否可达的过程。当所有的根都检查完毕后,堆中将包含可达(已标记)与不可达(未标记