参考资料:

http://www.cnblogs.com/zhguang/p/3257367.html

概要:

Java GC机制主要完成3件事:确定哪些内存需要回收,确定什么时候需要执行GC,如何执行GC。

从4个方面学习Java GC机制,
1,内存是如何分配的;
2,如何保证内存不被错误回收(即:哪些内存需要回收);
3,在什么情况下执行GC以及执行GC的方式;
4,如何监控和优化GC机制。

程序计数器也是所有JVM内存区域中唯一一个没有定义OutOfMemoryError的区域。

一般来说,一个Java的引用访问涉及到3个内存区域:JVM栈,堆,方法区。

通过直接指针访问的方式中,reference中存储的就是对象在堆中的实际地址,在堆中存储的对象信息中包含了在方法区中的相应类型数据。这种方法最大的优势是速度快,在HotSpot虚拟机中用的就是这种方式。

GC回收:

Java内存分配和回收的机制概括的说,就是:分代分配,分代回收。对象将根据存活的时间被分为:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)

在年轻代,进行的垃圾回收方法是著名的“停止-复制”清理法;

   

  年轻代(Young Generation):对象被创建时,内存的分配首先发生在年轻代(大对象可以直接被创建在年老代),大部分的对象在创建后很快就不再使用,因此很快变得不可达,于是被年轻代的GC机制清理掉(IBM的研究表明,98%的对象都是很快消亡的),这个GC机制被称为Minor GC或叫Young GC。注意,Minor GC并不代表年轻代内存不足,它事实上只表示在Eden区上的GC。

  年轻代上的内存分配是这样的,年轻代可以分为3个区域:Eden区(伊甸园,亚当和夏娃偷吃禁果生娃娃的地方,用来表示内存首次分配的区域,再贴切不过)和两个存活区(Survivor 0 、Survivor 1)。内存分配过程为(来源于《成为JavaGC专家part I》,http://www.importnew.com/1993.html):

    

  1. 绝大多数刚创建的对象会被分配在Eden区,其中的大多数对象很快就会消亡。Eden区是连续的内存空间,因此在其上分配内存极快;
  2. 当Eden区满的时候,执行Minor GC,将消亡的对象清理掉,并将剩余的对象复制到一个存活区Survivor0(此时,Survivor1是空白的,两个Survivor总有一个是空白的);
  3. 此后,每次Eden区满了,就执行一次Minor GC,并将剩余的对象都添加到Survivor0;
  4. 当Survivor0也满的时候,将其中仍然活着的对象直接复制到Survivor1,以后Eden区执行Minor GC后,就将剩余的对象添加Survivor1(此时,Survivor0是空白的)。
  5. 当两个存活区切换了几次(HotSpot虚拟机默认15次,用-XX:MaxTenuringThreshold控制,大于该值进入老年代,但这只是个最大值,并不代表一定是这个值)之后,仍然存活的对象(其实只有一小部分,比如,我们自己定义的对象),将被复制到老年代。

  从上面的过程可以看出,Eden区是连续的空间,且Survivor总有一个为空。经过一次GC和复制,一个Survivor中保存着当前还活着的对象,而Eden区和另一个Survivor区的内容都不再需要了,可以直接清空,到下一次GC时,两个Survivor的角色再互换。因此,这种方式分配内存和清理内存的效率都极高,这种垃圾回收的方式就是著名的“停止-复制(Stop-and-copy)”清理法(将Eden区和一个Survivor中仍然存活的对象拷贝到另一个Survivor中),这不代表着停止复制清理法很高效,其实,它也只在这种情况下高效,如果在老年代采用停止复制,则挺悲剧的。

年老代(Old Generation):对象如果在年轻代存活了足够长的时间而没有被清理掉(即在几次Young GC后存活了下来),则会被复制到年老代,年老代的空间一般比年轻代大,能存放更多的对象,在年老代上发生的GC次数也比年轻代少。当年老代内存不足时,将执行Major GC,也叫 Full GC。  

   可以使用-XX:+UseAdaptiveSizePolicy开关来控制是否采用动态控制策略,如果动态控制,则动态调整Java堆中各个区域的大小以及进入老年代的年龄。

  如果对象比较大(比如长字符串或大数组),Young空间不足,则大对象会直接分配到老年代上(大对象可能触发提前GC,应少用,更应避免使用短命的大对象)。用-XX:PretenureSizeThreshold来控制直接升入老年代的对象大小,大于这个值的对象会直接分配在老年代上。

  可能存在年老代对象引用新生代对象的情况,如果需要执行Young GC,则可能需要查询整个老年代以确定是否可以清理回收,这显然是低效的。解决的方法是,年老代中维护一个512 byte的块——”card table“,所有老年代对象引用新生代对象的记录都记录在这里。Young GC时,只要查这里即可,不用再去查全部老年代,因此性能大大提高。

java内存区域以及GC回收的更多相关文章

  1. Java 内存区域和GC机制分析

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  2. Java 内存区域和GC机制-java概念理解

    推荐几篇关于java内存介绍的文章 Java 内存区域和GC机制 http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html    ...

  3. Java内存区域和GC机制篇

    Java内存区域和GC机制一.目录 1.Java垃圾回收概括 2.Java内存区域 3.Java对象的访问方式 4.Java内存访问机制 5.Java GC 机制 6.Java垃圾收集器 二.Java ...

  4. 【转载】Java系列笔记(3) - Java 内存区域和GC机制

    Java系列笔记(3) - Java 内存区域和GC机制 转载:原文地址http://www.cnblogs.com/zhguang/p/3257367.html 目录 Java垃圾回收概况 Java ...

  5. Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  6. Java系列笔记(3) - Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  7. Java 内存区域和GC机制--备用

    Java垃圾回收概况 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代 ...

  8. JAVA内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  9. 转载:Java 内存区域和GC机制

    原文链接:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html 目录 Java垃圾回收概况 Java内存区域 Java对象的访 ...

随机推荐

  1. mysql之存储过程基础

    存储过程 procedure 可以理解为一个处理增删改,没有返回值得函数 创建存储过程的基本语法 create procedure 过程名 ([参数列表]) begin --过程体 end 存储过程主 ...

  2. pb datawindow的用法

    1. 使DataWindow列只能追加不能修改如何使DataWindow中的数据只能追加新记录而不能修改,利用 Column 的 Protect 属性可以很方便的做到这一点,方法如下:将每一列的 Pr ...

  3. JS实现带省略号的长分页显示

    // 刷新|生成分页信息 function refreshPageInfo(data, pageIndex) { var pageSize = data.pageCount pagingInfo.ht ...

  4. 【Git的基本操作六】分支管理

    分支管理 1. 什么是分支? 在版本控制过程中,使用对条线同时推进多个任务. 2. 分支的好处 同时并行推进多个功能开发,提高开发效率 各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任 ...

  5. vue项目使用openlayers来添加地图标注,标注样式设置的简要模板

    先把代码贴出来,注释以后有时间再写(需要留意一下这里图标的引入方式,函数内相同路径无法找到图片) import sk from "../../assets/img/home/sk-activ ...

  6. 短信对接——一种jdbc链接运用

    package sms; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamRead ...

  7. yii2 response多次输出问题的查找

    { "IsSuccess": 1, "ErrMsg": "OK", "Data": { "IsSuccess& ...

  8. 修改Vue中的 v-html 内的元素无效问题

    其原因就是在 style 样式中没有去处scoped 因为 v-html 会把内容当成子组件,而scoped 会在本身的组件中起作用

  9. 提升Scrapy框架爬取数据效率的五种方式

    1.增加并发线程开启数量 settings配置文件中,修改CONCURRENT_REQUESTS = 100,默认为32,可适当增加: 2.降低日志级别 运行scrapy时会产生大量日志占用CPU,为 ...

  10. Delphi 字段的操作

    樊伟胜