Java提供了gc机制,jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于 java 堆和方法区中,在程序运行期间,这部分内存的分配和使用都是动态的.垃圾回收机制,java不需要向C或者C++那样需要程序员自行释放内存,由编程人员释放资源,避免了资源释放错误和不必要的失误而带来的程序上的错误,java提供的垃圾回收机制会在程序执行的过程中自动的判断哪些资源不再被利用变成无用的资源,自动调用垃圾回收机制回收无用的资源。

内存分配上java用的HotSpot虚拟机,会把堆区(存放对象)分为两个区域:年轻代,年老代,两个物理区域的对象可以互相转移

年轻代(新生代):大部分对象都会存在这里,因为很多对象创建之后很快就会变得不可达,在这里进行的大都是比较小而且操作频繁的回收,花费的时间短
年老代(老年代):内存相对较大,那些在年轻代被存活下来的对象也会被放到这里,对象会保留时间较长的,都会分布在年老代,处在这里的对象大都是占用空间上升缓慢,并且回收频率较低的对象,花费的时间较长
其中还有一块叫做持久区的区域permanent generation,也叫方法区,存放的是类的信息,可能在这里发生gc但是主要还是在年轻代和年老代发生gc
在年老代里存在类似于身份证的区域card table,存放的是所有年老代d对象指向年轻代的对象的引用,当针对年轻代发生gc的时候,只需要来查询这里来决定是否回收,不用再去遍历整个年老代,这样虽然带来了内存的开销,但是节省了时间
详细介绍年轻代:年轻代又被分为三个区域,
  • 一个伊甸园空间(Eden ),非常自在的一块区域
  • 两个幸存者空间(Survivor )
  1. 最开始创建的对象会被存放在Eden伊甸园里
  2. 当Eden中的对象经历了一次gc之后存活下来的对象会被移动到一个幸存者空间里(survivor),之后
  3. 每次gc之后存活来的对象都会存放在同一个存活区,直到这个空间满了,如果还有存活的就会存放在另一个存活空间,之后清空饱和的那个幸存者空间,
  4. 经历过几次以上的步骤几次之后还在存活的对象,就会被移动到年老代里面
注意:刚刚创建的对象会保存在Eden里面的,对于那些长期存在的对象会从幸存区转移到年老代里
对于年老代的gc几乎发生在年老代满的时候,执行的过程会根据回收的类型利用不同的方式,
垃圾收集算法:
标记-清除”(Mark-Sweep)算法,算法分为“标记”和“清除”两个阶段:最开始标记那些需要进行回收的对象,在所有要回收的对象标记之后,执行清楚操作。回收无用的内存。

它的主要缺点有两个:一个是效率问题,标记和清除过程的效率都不高;另外一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

复制”(Copying)算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

这样使得每次都是对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。只是这种算法的代价是将内存缩小为原来的一半,持续复制长生存期的对象则导致效率降低。

标记-压缩/整理“算法:复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。

根据老年代的特点,有人提出了另外一种“标记-整理”(Mark-Compact)算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

分代收集算法

新生代中,每次垃圾收集时都有大批对象死去,只有少量存活,就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集;

老年代中,其存活率较高、没有额外空间对它进行分配担保,就应该使用“标记-整理”或“标记-清理”算法进行回收。

JDK7一共有5种GC类型:

  1. Serial GC
  2. Parallel GC
  3. Parallel Old GC (Parallel Compacting GC)
  4. Concurrent Mark & Sweep GC  (or “CMS”)
  5. Garbage First (G1) GC
Serial GC:该回收算法第一步会先标记依然存活的对象,第二步,从头开始检查堆内存,清理那些死亡的对象,保留存活的对象
Parallel GC:与第一种算法最大的区别就是采用了多线程,效率会更高
Parallel Old GC (Parallel Compacting GC):算法和Parallel GC只在清理的步骤不一样,会把对象放到一个预先处理好的区域
CMS GC:所用的时间最少,也是最先标记,在标记的时候,其他线程依然会运行,节省时间,带来的缺点,就是相比于其他的gc会占用更多的内存和cpu资源,因为在标记的时候其他线程也在运行,默认情况下,这种回收算法回收的内存空间不是压缩的,不是连续的,前两个都是连续的,会导致内存碎片,只是节省了时间
G1 GC:一种最快的回收算法,他没有年轻代和老年代的概念,每次创建的对象会放在一个区域的不同的格子上,直到满了会执行一次gc,但是目前不稳定。
一般情况下调优不会介绍
JVM 调优主要在3点:
1. 选择合适的 GC collector.
2. 指定合适的 heap area大小.
3. 指定young generation的比例(或大小),它影响到 Full GC发生的频率以及应用暂停时间.

参考:
周志明. 深入理解Java虚拟机[M]. 北京:机械工业出版社, 2013: 61-100.

转载于:https://www.cnblogs.com/duzhentong/p/7816593.html

Java GC垃圾回收机制相关推荐

  1. java垃圾回收机制_乐字节Java|GC垃圾回收机制、package和import语句

    本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...

  2. 不要再问我“Java GC垃圾回收机制”了

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底 ...

  3. java gc 有钱人_小猿圈java之GC垃圾回收机制

    垃圾回收机制是提高性能的重要机制,所以不管学什么语言也好,垃圾回收机制都是有的,也是很重要的,小猿圈这章详解一下java的GC垃圾回收机制,需要用的或者感兴趣的朋友们,可以跟着小编学习一下. 一.GC ...

  4. java如何关闭gc,GC垃圾回收机制,

    GC垃圾回收机制, 个人理解: 因为在使用JAVA创建一个类或者对象后,难免会存在以后不使用的情况,为了减少其继续再占用内存,必须建立一套清理垃圾的机制,但是怎么判断什么样的才算是不使用的垃圾呢,这里 ...

  5. java的垃圾回收机制包括:主流回收算法和收集器(jvm的一个主要优化方向)

    2019独角兽企业重金招聘Python工程师标准>>> java的垃圾回收机制是java语言的一大特色,解放了开发人员对内存的复杂控制,但如果你想要一个高级java开发人员,还是需要 ...

  6. JVM架构和GC垃圾回收机制--面试

    JVM架构和GC垃圾回收机制详解 JVM架构图分析 下图:参考网络+书籍,如有侵权请见谅 (想了解Hadoop内存溢出请看: Hadoop内存溢出(OOM)分类.参数调优化) JVM被分为三个主要的子 ...

  7. JAVA虚拟机垃圾回收机制和JAVA排错三剑客

    一.Java虚拟机逻辑回收机制 1.Java垃圾回收器 Java垃圾回收器是Java虚拟机(JVM)的三个重要模块(另外两个是解释器和多线程机制)之一,为应用程序提供内存的自动分配(Memory Al ...

  8. 【Java】Java的垃圾回收机制小结

    文章目录 1. Java的垃圾回收机制? 1.1 Java的引用类型 1.2 哪些内存需要回收? 1.3 怎么定义垃圾? 1.4 怎么回收垃圾? 2. JVM一次完整的GC流程? 3.触发GC之后,会 ...

  9. 什么是GC对于GC垃圾回收机制的理解

     什么是GC,GC就是垃圾回收机制:在系统运行过程中,会产生一些无用的对象,这些对象占据着一定的内存,如果不对这些对象清理回收无用对象的内存,可能会导致内存的耗尽,所以垃圾回收机制回收的是内存.同 ...

最新文章

  1. 匹配3位或4位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔...
  2. 数据结构Queue:poll、offer、element、peek
  3. 已解决:Unable to register authentication agent: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed:
  4. Android7.1选择时区由默认的GMT+00:00改为GMT+08:00中国标准时间
  5. Go中的Map实现机制
  6. 你真的了解 i++, ++i 和 i+++++i 以及 i+++i++ 吗?
  7. CSDN博客文章写作技巧
  8. boost::geometry::detail::copy_segments的用法测试程序
  9. as和强制类型转换的区别
  10. excel工具箱_Excel工具箱15.54安装教程
  11. 2022软工K班个人编程任务
  12. excel转word后表格超出页面_excel转word后表格显示不全
  13. 单片机点亮LCD1602A液晶屏
  14. 快狐未能连接服务器,航海王强者之路好友福袋开启详细介绍_快狐快狐视频app...
  15. 现代大学英语精读第二版(第三册)学习笔记(原文及全文翻译)——6B - They Dared Cocaine—and Lost(尝试可卡因后,他们迷失了)
  16. 三万元存一年,利息是多少?银行工作人员:这么存最合算!
  17. 掷一枚硬币,直到连续出现两次正面朝上的时候停止,问掷硬币次数的期望
  18. python conda无法安装包 报错An HTTP error occurred when trying to retrieve this URL.
  19. Java是剑客,.NET是刀客
  20. 【pthread_cancel函数:避免踩坑】

热门文章

  1. GDCM:gdcm::StreamImageWriter的测试程序
  2. GDCM:gdcm::Object的测试程序
  3. ITK:将样条曲线拟合到点集
  4. DCMTK:OFtuple的单元测试
  5. VTK:网格之Decimation
  6. VTK:图片之BorderPixelSize
  7. VTK:IO之ReadPNM
  8. OpenGL 实例化属性的实例
  9. C语言中基本的不平衡二进制搜索树实现(附完整源码)
  10. QT的QQmlScriptString类的使用