首先需要澄清的是,垃圾收集(GC)的历史远比Java要久远,当我们意识到手动管理内存所带来的麻烦时,懒惰的天性推动先驱们寻找更为简单、易用、关键是傻瓜式的内存管理技术。GC技术起源于1960年诞生于MIT的Lisp语言,由此可见越聪明的人越懒惰。

 
        最近有一种想法:程序开发,程序设计从本质上来讲是个哲学问题,虽然我们要解决的问题是现实在程序世界中的投射,那么问题本身就应该在现实世界中有相应的解决,而且我们也一直在模拟现实世界,由过程式,面向对象以及函数式编程以及我们下面所要看到的GC的设计思想可见。
 
        因为不想根据运行环境的不同修改代码,我们希望有一个缓冲层能屏蔽底层硬件环境的不同,于是我们引入了JVM
 
        因为有人工管理内存存在的不确定,JVM的设计者们引入了内存自动分配与垃圾收集
 
        因为想要最大限度的利用内存,JVM内存被划分为线程内存(栈)与共享内存堆
 
        为了能够更有效的分配及回收内存,堆被划分成了新生代与老年代,这样才能根据对象的不同采用更加具有效率的GC方案。
 
        也是因为不同GC方案的需求,新生代又被划分为Eden区和survivor区
 
        |---------- 新生代------------|------老年代------|
        |Eden|survivor|survivor|          old             |
 
        ....
 
        1. 程序计数器、虚拟机栈、本地方法栈三个区域随这线程生死,其内存分配都具有确认性,因此不必过多考虑,我们所说的内存分配与回收通常是指的堆
 
        2. 我们怎么判断一个对象”死了“,也就是可以回收的
 
                2.1 引用计数器方法(未使用)
 
                        最直观的方法,对象如果被引用,则引用计数+1,如果去引用,则引用计数-1,如果为0,则对象没有引用,可以被回收。但该算法无法解决循环引用的问题。JAVA虚拟机也没有采用该算法。
 
                2.2 根搜索算法 GC Root Tracing(Java、C#、Lisp)
 
                        通过一系列的名称”GC Root“的对象作为起始点,从该节点向下搜索,走过的路径称为引用链,所有不在任意一条引用链上的对象(不可达)就可以判断为不可用。
 
                        该算法需要确定Root点,在JAVA中包括如下几种:虚拟机栈中本地变量表所引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈JNI中引用的对象
 
                2.3 finalize
 
                        在finalize块中我们可以设置对象被重新引用,从而躲过GC,但不推荐在Finalize快中进行任何操作。因在finalize中的代码块会被放置在一个队列中执行,且不保证执行结果。
 
                       
 
        3. 引用
 
                Java的引用可以分为强引用(Strong Reference)、软引用(SoftReference)、弱引用(WeakReference)、虚引用(PhantomReference)这四种,并且引用是由强到弱。
 
                强引用是代码中普遍存在的,类似于Object obj = new Obeject()类的引用,其永远不会被回收
 
                软引用用来描述一些还有用,但并非必须的对象,在发生内存溢出前,会对软引用的对象进行二次回收,仍无法分配内存时才会抛出异常。
 
                弱引用用来描述非必须对象,被弱引用关联的对象智能生存到下一次GC之前
 
                虚引用是最弱的引用关系,其不会对对象产生影响,其设置的唯一目的就是在对象被回收时收到一个系统通知。
 
        4. 方法区的回收
 
                方法区也是有垃圾收集的,只是效果通常不好。方法区(永久代)的垃圾收集主要包括两部分内容:废弃常量和无用的类。在大量使用反射、动态代理、GClib等bytecode的场景都需要虚拟机的卸载功能,以保证方法区不会溢出。
 

深入理解Java虚拟机 - 垃圾收集概述的更多相关文章

  1. 深入理解java虚拟机----->垃圾收集器与内存分配策略(下)

    1.  前言 内存分配与回收策略 JVM堆的结构分析(新生代.老年代.永久代) 对象优先在Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保  2.  垃圾 ...

  2. 深入理解Java虚拟机 - 垃圾收集算法与垃圾收集器

    1. 垃圾收集算法       JVM的垃圾收集算法在不同的JVM实现中有所不同,且在平时工作中一般不会深入到收集算法,因此只对算法做较为简单的介绍.       1.1 标记-清除算法        ...

  3. 深入理解JAVA虚拟机 垃圾收集器和内存分配策略

    引用计数算法 很多教科书判断对象是否存活的算法是这样的:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不可能再被使用的 ...

  4. 深入理解Java虚拟机-垃圾收集算法

    一.判断对象是否可进行回收 1.引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的.但是主流的 ...

  5. 深入理解java虚拟机---垃圾收集器和分配策略-1

    博文重点: 学习目标:哪些内存需要回收 什么时候回收    如何回收 在基于概念讨论的模型中,主要对Java堆和方法区进行讨论. why?:一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个 ...

  6. [深入理解Java虚拟机]<垃圾收集器与内存分配策略>

    Overview 垃圾收集考虑三件事: 哪些内存需要回收? 什么时候回收? 如何回收? 重点考虑Java堆中动态分配和回收的内存. Is Object alive? 引用计数法 给对象添加一个引用计数 ...

  7. 深入理解java虚拟机--垃圾收集器

    对象的销毁 对象的finalize方法只会执行一次,在finalize里可以自救不被销毁,二次被主动gc,必定会销毁 类销毁

  8. 《深入理解Java虚拟机》(三)垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 详解 3.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第三章 ,为了整理思路,简单记录一下,方便后期查阅. 3.2 对象已死吗 在垃圾收集器进行回收 ...

  9. 《深入理解java虚拟机》第三章 垃圾收集器与内存分配策略

    第三章 垃圾收集器与内存分配策略 3.1 概述 哪些内存需要回收 何时回收 如何回收 程序计数器.虚拟机栈.本地方法栈3个区域随线程而生灭. java堆和方法区的内存需要回收.   3.2 对象已死吗 ...

随机推荐

  1. mac下安装redis

    安装php_redis.so 首先用git从https://github.com/nicolasff/phpredis下载源码.然后依次执行以下命令 sudo /Applications/XAMPP/ ...

  2. laravel扩展图片处理Intervention Image

    github地址:https://github.com/Intervention/image

  3. try catch finally 关闭流标准的写法

    平常开发中,都知道要在finlly里关闭流,但是有时finlly里代码不当,会引起另外的异常. 以下是看struts2源代码看到的,随手记录下. 有两点注意: (1)判断流是否为空. (2)filly ...

  4. Demo学习: Collapsible Panels

    Collapsible Panels 设置TUniPanel布局属性,布局属性在Ext里是比较常用的属性,当前版本虽已经提供了布局功能,但很不完善,比如当Panel.TitlePosition=tpR ...

  5. what is the virtual machine, when and why we need use it ?

    虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的.运行在一个完全隔离环境中的完整计算机系统. 通过虚拟机软件,你可以在一台物理计算机上模拟出二台或多台虚拟的计算机,这些虚 ...

  6. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  7. Lua中cJson的读写

    这里采用的是Lua CJson库,是一个高性能的JSON解析器和编码器,其性能比纯Lua库要高10~20倍.并且Lua Json完全支持UTF-8,无需以来其他非Lua/LuaJit相关包. 环境安装 ...

  8. TF/IDF计算方法

    FROM:http://blog.csdn.net/pennyliang/article/details/1231028 我们已经谈过了如何自动下载网页.如何建立索引.如何衡量网页的质量(Page R ...

  9. iOS工程中的info.plist文件

    我们建立一个工程后,会在Supporting files下面看到一个"工程名-Info.plist"的文件,这个是对工程做一些运行期配置的文件,很重要,不能删除. 如果你在网上下载 ...

  10. [转载]c# winform 获取当前程序运行根目录

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnostics.Process.G ...