首先需要澄清的是,垃圾收集(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. 解决FPDF报错:FPDF error: Not a JPEG file / FPDF error: Not a PNG file

    最近有个项目需要用到FPDF,但是输出的时候报错: FPDF error: Not a JPEG file: http://***/data/attachment/forum/201603/19/10 ...

  2. PHP获取当前时间的毫秒数(yyyyMMddHHmmssSSS)

    1 second = 1000 millisecond = 1000,000 microsecond = 1000,000,000 nanosecond php的毫秒是没有默认函数的,但提供了一个mi ...

  3. 找不到 com.google.zxing.ResultMetadataType 异常解决

    在 https://github.com/zxing/zxing 下载二维码扫描 将 android 导入,code打成jar包运行时 报 06-14 23:43:08.690: E/AndroidR ...

  4. class_create(),device_create自动创建设备文件结点

    class_create(),device_create自动创建设备文件结点 从linux 内核2.6的某个版本之后,devfs不复存在,udev成为devfs的替代.相比devfs,udev有很多优 ...

  5. html 页面 ajax 方法显示遮罩

    showLoading.css 样式: ;;list-style-type:none;} a,img{;} .overlay{;;;;;width:100%;height:100%;_padding: ...

  6. Android Studio 单刷《第一行代码》系列目录

    前言(Prologue) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Android ...

  7. Oralce11 客户端的安装和 PlSql Developer 的配置

    关于Oracle11服务器端安装时的配置问题我就不讲了,就是要安装DataBase1和DataBase2. 现在我来讲的是Oralce11 客户端的安装和PlSql的配置问题: 步骤一:选择图示,wi ...

  8. shell复习笔记----命令与参数

    shell最基本的工作就是执行命令. 每键入一道命令, shell 就会执行. $cd work;ls -l whizprog.c 首先:格式很简单,以空白(Space 键或者 Tab键)隔开命令行中 ...

  9. C# Winform 涉及的拖放操作总结

    在开发程序的时候,为了提高用户的使用体验,或满足相关用户的功能,总是离不开拖放功能.而本文是总结winform下的常用拖放操作.主要有 1.textbox接受拖放的文件2.listbox允许用户自定义 ...

  10. Extjs4.2布局——Ext.container.ViewportView

    先贴出官方文档的关于此布局的描述:“ 一个专门的容器用于可视应用领域(浏览器窗口). Viewport渲染自身到网页的documet body区域, 并自动将自己调整到适合浏览器窗口的大小,在窗口大小 ...