前言

线程独享的内存区域有程序计数器,虚拟机栈,本地方法栈,这些区域不用考虑内存回收的问题,随着线程的执行结束,自然就回收了,而堆内存和方法区的回收则不一样,他们的内存分配和回收是动态的。

1.对象存活与否

  • 法一:引用计数算法
  • 原理:每当有地方引用该对象时,计数器加一,当引用实效的时候,计数器减一,当计数器值为0的时候可以进行对象的内存回收。
  • 问题:无法解决对象之间的循环引用
  • 法二:可达性分析
  • 原理 :1.选择一系列的对象作为GC Roots(GC ROOTS:栈帧中的局部变量表中的对象引用,方法区中静态属性引用,常量池中的常量引用),其实我觉得除了object5=null这种情况之外都可以作为GC ROOTs
  • 2.如果对象之间存在引用关系,那么它们之间就应该可达,eg:Object1于Object2
  • 3.从GC ROOTs进行可达性分析如果不可达那么久认为对象可以被回收(eg:object5,object6,object7)
  • 图1.可达性分析算

2.对象的垃圾回收过程---对象的二次标记过程(回收堆内存)

  • 1.进行可达性分析,发现对象不可达,则进行第一次标记
  • 2.第一次标记后的对象将会检查对象是否有覆盖finalize方法以及finalized()是否被执行过。
  • 3.finalized()函数没有被执行过的对象会被放入F-Queue队列中,执行finalized()函数,若执行过程中对象被重新引用,那么在第二次标记时该对象将会被移出F-Queue,否则对象会被回收。

3.回收方法区(加载过的类、常量池、静态变量)

  • 回收对象:1.没用的类 2.无用常量
  • 什么样的类才是没用的类?
  • 无用常量:没有被引用的常量
  • 无用类:
  • 1.该类的所有实例已经被回收
  • 2.类的加载器已经被回收(CLASSLOAD)
  • 3.该类的CLASS对象没有被使用

4.垃圾回收算法

  • 总体思想:标记-清楚算法
  • 阶段一:对需要回收内存的对象进行标记
  • 阶段二:对标记过的内存进行回收
  • 问题:
  • 1.效率低下
  • 2.产生大量的内存碎片

图2:标记-清除算法

  •  新生代对象的回收算法
  • 复制法
  • 1.新生代对象需要回收的对象数量比较少
  • 2.为了解决标记-清除算法效率低下的问题,我们把内存分为两部分,Eden和两块Survivor(8:1:1),Eden内存用完,进行垃圾回收之前,会把Eden上的存活的对象复制到survivor上,之后对Eden进行整块回收

图3.复制法回收新生期内存

  • 老年代对象回收算法
  • 标记-整理
  • 老年代的对象存活时间比较旧,甚至会出现100%存活的极端情况,因此复制法不再适用。
  • 阶段一:标记
  • 阶段二:整理,先不对内存进行回收,而是把存活的对象向内存的一端进行移动,然后直接清除掉边界以外的内存。

4.何时进行垃圾回收

  • safepoint
  • 为了避免程序长时间执行,往往会在代码复用较多的地方设置safepoint,例如方法跳转,循环跳转,异常跳转
  • 进行垃圾回收之前需要所有的线程在safepoint停下来,为了达到同步有两种方式
  • 1.抢先试:先中断所有的线程,然后让线程,自己“跑”到最近的safepoint
  • 2.主动式:在safepoint处设置一个轮训标志,当线程发现标志设置为true时,就会在轮询的位置停下来
  • safeRegion
  • 当线程分配不到CPU时间片的时候,线程自然就不能跑到safepoint,这时就要以来saferegion进行垃圾回收
  • saferegion是指在一片代码中对象的引用关系不发生变化的时候。

5.垃圾回收器

  • 目前常见的垃圾回收器如图所示

图4.虚拟机的垃圾回收器

  • 简单介绍
  • 1.Serial
  • 新生期对象的单线程收集器,需要首先停止用户线程(stop the world)
  • 2.Serial Old
  • 老年期单线程,也需要停止用户线程
  • 3.ParNew
  • 新生期对象的多闲扯功能收集器
  • 4.Parallel Scavenge
  • 与Serial回收器类似是新生对象的垃圾回收器,Serial追求的是是的垃圾回收所占用的CPU时间尽量的短,而Parallel Scavenge追求的是最大吞吐量  (运行用户程序时间)/(运行用户程序时间+垃圾回收的时间)
  • 6.Parallel Old
  • Parallel Scavenge的老年版本
  • 5.CMS
  • 基于标记-清除的老年代垃圾回收器,分为如下四个步骤
      • 初始标记--GC Roots直接关联的对象
      • 并发标记--GC Roots Tracing的过程(与用户程序并发)
      • 重新标记--并发标记过程中,用户程序新长生的对象进行标记
      • 并发清理--进行垃圾回收
  • 7.GI
  • 与CMS类似,并发清理变为筛选回收,加快回收的效率,还没有成熟版本

2.JAVA垃圾回收机制的更多相关文章

  1. 【转载】Java垃圾回收机制

    原文地址:http://www.importnew.com/19085.html Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联 ...

  2. 【转】深入理解 Java 垃圾回收机制

    深入理解 Java 垃圾回收机制   一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  3. 深入理解java垃圾回收机制

    深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  4. Java垃圾回收机制_(转载)

    Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来.在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给 ...

  5. 成为Java GC专家(3)—如何优化Java垃圾回收机制

    为什么需要优化GC 或者说的更确切一些,对于基于Java的服务,是否有必要优化GC?应该说,对于所有的基于Java的服务,并不总是需要进行GC优化,但前提是所运行的基于Java的系统,包含了如下参数或 ...

  6. java 垃圾回收机制 引用类型

    Java语言的一个重要特性是引入了自动的内存管理机制,使得开发人员不用自己来管理应用中的内存.C/C++开发人员需要通过malloc/free 和new/delete等函数来显式的分配和释放内存.这对 ...

  7. 【Java】Java垃圾回收机制

    Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来.在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给 ...

  8. Java垃圾回收机制的工作原理

    Java垃圾回收机制的工作原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 获取更多内容,请关注小编个人微信公众平台: 一.Java中引入垃圾回收机制的作用 ...

  9. Java 垃圾回收机制(早期版本)

    Java 垃圾回收机制在我们普通理解来看,应该视为一种低优先级的后台进程来实现的,其实早期版本的Java虚拟机并非以这种方式实现的. 先从一种很简单的垃圾回收方式开始. 引用计数 引用计数是一种简单但 ...

  10. 深入理解 Java 垃圾回收机制

            深入理解 Java 垃圾回收机制 一:垃圾回收机制的意义 java  语言中一个显著的特点就是引入了java回收机制,是c++程序员最头疼的内存管理的问题迎刃而解,它使得java程序员 ...

随机推荐

  1. (简单) POJ 1797 Heavy Transportation,Dijkstra。

    Description Background Hugo Heavy is happy. After the breakdown of the Cargolifter project he can no ...

  2. hibernate---一级缓存, 二级缓存, 查询缓存

    缓存: 内存开辟一块空间,把本来存在硬盘的东西放在内存里, 以后从内存读取. 一级缓存: session级别的缓存, session.load 二级缓存: 总的缓存.

  3. CORBA技术及实例

    CORBA技术及实例 CORBA是一种规范,它定义了分布式对象如何实现互操作.在WorldWideWeb盛行之前,非凡是java编程语言风靡之前,C++开发者基本将CORBA作为其高端分布式对象的解决 ...

  4. Android小功能之垂直滚动条

    <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android=" ...

  5. 史上最坑的证书报错解决方法:Code=3000 "未找到应用程序的“aps-environment”的权利字符串"

    在ios注册远程通知获取设备令牌token的时候 // 注册远程通知获取设备令牌 toKen [[ UIApplication sharedApplication ] registerForRemot ...

  6. Python学习【第十二篇】模块(2)

    序列化 1.什么是python序列化? 把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling 序列化就是将python的数据类型转换成字符串 反序列化就是将字符串转换成 ...

  7. javascript--hasOwnProperty()+isPrototypeof()+in方法

    1.hasOwnProperty():用来检测对象中是否包含给出的函数属性或者对象,但是无法检测出对象的原型链中是否包含给出的属性或对象--该属性或者对象必须在函数内部被声明 2.isPrototyp ...

  8. Python爬虫框架Scrapy安装使用步骤

    一.爬虫框架Scarpy简介Scrapy 是一个快速的高层次的屏幕抓取和网页爬虫框架,爬取网站,从网站页面得到结构化的数据,它有着广泛的用途,从数据挖掘到监测和自动测试,Scrapy完全用Python ...

  9. C#键盘事件处理(来源网上)

    C#键盘事件处理 如果你希望用户按F1弹出chm帮助,代码如下: private void FrmMain_Load(object sender, EventArgs e) { this.KeyPre ...

  10. linux 5个查找命令

    1. find find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件. find的使用格式如下: $ find <指定目录> <指定条件> <指定动作> ...