一.Java的垃圾回收机制

Java的垃圾回收机制(java garbage collection)是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的堆内存空间。

注意粗体字的地方,java的垃圾回收线程是优先级比较低的线程,什么时候进行垃圾回收难以确定。当某些对象被标记为垃圾对象后,等垃圾回收线程运行时,就会将这些对象回收(确切的说应该是回收这些对象所占的堆内存空间)。

二.什么样的对象会被标记成垃圾对象呢?

  1. 一般来说,所有指向对象的引用都已失效,不可能再有程序能调用到这个对象,那么这个对象就成了垃圾,应该被回收。
  2. 根据这个思路,很容易就能想到用《引用计数》的办法来确定一个对象是否是垃圾。即每当多一个引用指向对象时,引用计数加一,每当少一个引用指向对象时,引用计数减一,引用计数减到零,对象就可以被回收了。
  3. 然而引用计数有一个致命问题不好解决,就是循环引用的问题。比如说一个循环链表,他们循环引用者,引用计数永远不会为零,但是实际上程序已经不能访问他们了,他们应该被回收。(如果还没明白循环引用,第五步之后有代码说明)
  4. 所以Java实际上是使用基于GC Roots的可达性分析,什么是GC Roots?所有类的静态变量,每个线程调用栈上的本地变量(实际上我们编程时也是要从这些地方开始访问数据),所有这些对象,以及被这些对象所指向的对象,都是活的对象。活的对象所指向的对象也是活的对象。GC通过有向图的进行可达性分析,不可达的对象就被视为是垃圾对象。
  5. 所以只要在GC的时刻,让程序暂停运行,然后从GC Roots开始分析,最后没有被标记为活对象的对象就是垃圾了。

*代码事例解释什么是循环引用:

   

  如上图所示,假设我们有两个类分别是A和B,A类中有一个字段是B类的类型,B类中有一个字段是A类类型,现在分别new一个A类对象和new一个B类对象,此时引用a指向刚new出来的A类对象,引用b指向刚new出来的B类对象,然后将两个类中的字段互相引用一下,这样即使下面进行a = null和b = null,但是A类对象仍然被B类对象中的字段引用着,尽管现在A类和B类独享都已经访问不到了,但是引用计数却都不为0.

三.Java中有哪几种引用

  • 强引用(StrongReference):强引用就是我们平时使用的引用,是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它(结合上面,一个对象有强引用,那么这个对象一定可达,也就是说明这个对象是活的)。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。(简记:永不回收)
  • 软引用(SoftReference):如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。所以,软引用可用来实现内存敏感的高速缓存。(简记:内存不足再回收)
  • 弱引用(WeakReference):弱引用与软引用的区别在于:弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。(简记:遇到就回收)
  • 虚引用(PhantomReference):“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。(简记:形同虚设)

值得区分的一点是,软引用和弱引用是可选的时候和引用队列联合使用,如果与引用队列联合使用,那么当所引用的对象被垃圾回收,Java虚拟机就会把这个弱(或软)引用加入到与之关联的引用队列中。而虚引用是必须和引用队列联合使用。

记录Java的垃圾回收机制和几种引用的更多相关文章

  1. java JVM垃圾回收机制

    Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放控件,既要写构造函数,又要写析构函数,很多时候都 ...

  2. JVM系列(三):java的垃圾回收机制

    java垃圾回收机制介绍    上一篇讲述了JVM的内存模型,了解了到了绝大部分的对象是分配在堆上面的,我们在编码的时候并没有显示的指明哪些对象需要回收,但是程序在运行的过程中是会一直创建对象的,之所 ...

  3. 了解java中垃圾回收机制

    Java的垃圾回收机制是Java环境自带有的,它不像c语言的malloc申请空间后需要Free()函数来释放,而Java中的代码块中所申请的空间可在程序执行完成后自动释放,但是是有局限性的,代码块所占 ...

  4. 面试官,不要再问我“Java GC垃圾回收机制”了

    Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解> ...

  5. 【Java学习笔记】Java的垃圾回收机制

    搬以前写的博客[2014-12-30 15:07] 以前很少关注内存的问题,基本没有关注,这方面的小白,原因在于自己都是写的自我娱乐的小程序,不关注性能,不是提供服务.而企业级别的应用在程序稳健性方面 ...

  6. JAVA的垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  7. 全面分析Java的垃圾回收机制

    Java的堆是一个运行时数据区,类的实例(对象)从中分配空间.Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new.newarray.anewarray和mult ...

  8. Java内存垃圾回收机制(转贴)

    Java的堆是一个运行时数据区,类的实例(对象)从中分配空间.Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通 过new.newarray.anewarray和mul ...

  9. 浅析JAVA的垃圾回收机制(GC)

    1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制. 注意:垃圾回 ...

随机推荐

  1. android resources使用总结

    http://developer.android.com/guide/topics/resources/more-resources.html http://developer.android.com ...

  2. Spring应用——事务管理

    事务基础:请参看:http://www.cnblogs.com/solverpeng/p/5720306.html 一.Spring 事务管理 1.前提:事务管理器 在使用 Spring 声明式事务管 ...

  3. $.ajax、$.post、from表单序列化工具

    $.ajax\$.post <script type="text/javascript" language="javascript" src=" ...

  4. .Net Oauth2.0 第三方登录开发(Facebook ,LinkedIn )

    需求:OAuth2实现第三方网站授权并获取其相关数据来实现登录等功能 暂时支持Facebook ,LinkedIn ,基本大同小异,只是返回时的数据不同,需根据具体返回类型进行相应处理 1.OAuth ...

  5. 重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient

    [源码下载] 重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient 作者:webabcd 介绍重新想象 Windows 8.1 Store ...

  6. 解决死锁SQL

    USE [master]GO/****** Object: StoredProcedure [dbo].[p_lockinfo] Script Date: 04/03/2014 15:12:40 ** ...

  7. fibonacci数列的和取余(2)

    Maybe ACMers of HIT are always fond of fibonacci numbers, because it is so beautiful. Don't you thin ...

  8. C#中的索引器原理

    朋友们,还记得我们在C#语言开发中用到过索引器吗? 记得在获得DataGridView控件的某列值时:dgvlist.SelectedRows[0].Cells[0].Value; 记得在获得List ...

  9. JVM的ClassLoader过程分析

    本文来自网络:深入分析Java ClassLoader原理 http://my.oschina.net/zhengjian/blog/133836 一. JVM的ClassLoader过程以及装载原理 ...

  10. 设计模式之Builder (创建者模式)的一些个人理解(转)

    对于Builder模式很简单,但是一直想不明白为什么要这么设计,为什么要向builder要Product而不是向知道建造过程的Director要.刚才google到一篇文章,总算清楚了.在这里转贴一下 ...