美文网首页
Java垃圾回收机制

Java垃圾回收机制

作者: 海是倒过来的天_67f2 | 来源:发表于2018-08-07 12:07 被阅读0次

1.OutOfMemoryError(内存溢出)

一个应用中所占内存的大小包括:

Java堆的大小

线程栈

I/O缓冲区

原生库所分配的内存

随着产品功能的需求原来越多,应用越来越大,它所需要的内存也会随之增多,当一个应用耗尽了内存且JVM GC垃圾回收器也无法回收到任何对象空间时,就会发生内存溢出错误。内存溢出和内存泄露是两个完全不同的感念。内存溢出是指应用在申请内存时没有足够的内存供其使用,比如申请了一个Integer但是却给它存放了一个long型的数据,就是内存溢出;而内存泄露是指应用申请到内存并使用完全后,却无法释放已经申请的内存控件。

2.垃圾对象的判断

1.引用计数法

给每一个对象添加一个引用计数器,每当有一个地方引用它时,计数器就加1,当一个地方不再引用时,计数器减1,当计数器表为0时,视为该对象没有被任何地方引用。

引用计数器实现简单,且效率高,但是有一个巨大的缺点的不能处理循环引用的情况。

2.可达性分析法

该算法的基本思想是通过一些列称之为“GC Roots”的对象作为起点。从这些起点向下搜索,搜索所走过的路称之为引用链,当一个对象到GC Roots没有任何引用链(既GC Roots到对象不可达的时候),则证明该对象是不可用的。可以作为GC Roots的对象包括下面几种:

(1) 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中的引用对象

(2) 方法区中的静态属性引用的对象

(3) 方法区中常量的引用

(4)本地方法栈中JNI(Native方法)引用的对象

3垃圾回收算法

1.标记-清除(Mark-Sweep)算法

标记清除算法是Java中最基础的垃圾清除算法,其主要分为“标记”和“清除”两个阶段,首先从根集合开始扫描,对存活的对象进行标记,标记完成后,扫描整个空间中未被标记的对象进行回收,如下图所示

标记清除算法的缺点:

1.效率问题:标记和清除两个过程的效率都不太高

2.空间问题:标记清除算法不进行对象的移动,并且仅对不存活的对象进行处理,因此标记清除算法执行之后会产生大量不连续的内存碎片。这就可能会导致以后如果有对象需要大内存的控件时而无法找到足够连续的内存空间,此时不得不再次触发标记清除算法。

2.复制算法

复制算法是将内存按照容量划分成大小相等的两块,每次只使用其中的一块。当这一块内存使用完后,将还存活的对象复制到另一块上面,然后再把使用过的内存空间清空。这种算法使用了存活效率低的场景,比如说新生代。这样使得每次都是对整个搬去进行内存回收,内存分配时就不用考虑内存碎片的问题,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效,示意图如下:

现实中复制算法广泛的应用于商用的虚拟机中来回收新生代对象

3.标记整理算法

标记清除算法效率不高同时容易产生大量的空间碎片,而复制算法需要浪费额外的50%的控件且对对象存活较高时进行复制操作,效率太低,因此结合两则的优点提出了标记整理算法。该算法在

在标记过程中类似于标记清除算法,但是标记结束后不是立刻进行清除,而是让存活的对象向一端移动,最后直接清理掉边界以外的元素,该算法使用了存活率较高的场景(例如老年代)。示意图如下:

标记整理算法和标记清除算法最大的区别在于标记后需不需要对对象进行移动标记整理算法示意图如下

4.分代收集算法

对于一个大型的系统,创建的对象和变量一定很多,内存消耗也必定很大。无论单一的使用哪种分类算法都不能很好的满足需求,因此提出了分代收集算法:对于不同对象的生命周期(存活时间)不一样,而不同生命周期的对象位于堆中的不同区域,因此对堆内存中不同区域采用不同策略今次那个回收可以提高JVM的执行效率。一般情况下对于新生代对象存活率低的情况采用复制算法,老年代存活率较高额情况就采用标记清除或者标记整理算法。Java堆内存一般可以分为新生代,老年代和永久代(PermGen)三个模块。

在Java1.8中已经废弃了永久代,而是采用元空间(Metaspace)替代原因是在内存不足时如果采用永久代不发生内存移除OOM的情况,因此采用元空间。元空间和永久代最大的区别在于永久代位于虚拟机中,而元空间使用的是本地内存。

5.降低GC的调优的策略

1.调整HEAP堆中个区的大小,找到一个平衡点,再不发生OOM的情况下满足响应时间个吞吐量的需求。

增大内存,可以减小GC的执行频率,但是会增加GC的的执行时间

减小内存,可以减少GC的执行时间,但是会增加GC的执行频率

2.内存不做调整

3.避免主动触发GC

程序调用了System.gc()方法会触发FULL GC

在命令行中加入-XX:+DisableExolicitGC,可以忽略主动的GC调用。

6.Minor gc,full gc的触发条件

Minor GC的触发条件:当Eden区不足时

full gc的触发条件:老年代空间不足,允许分配空间失败。

gc与非gc时间耗时超过了GCTimeRatio的限制引发OOM

7.垃圾回收算法的触发条件

1.java无法再为新的对象分配内存空间

2.手动调用System.gc()(尽量不适用此方法)

因为:1.手动调用gc()方法,JVM并不会立即进行垃圾回收,也是需要等到合适的是时机才会调用gc方法。

2.加大虚拟机的压力

3.低优先级的gc线程,被运行时就会进行垃圾回收

相关文章

  • Java垃圾回收详解

    深入理解 Java 垃圾回收机制 深入理解 Java 垃圾回收机制 一:垃圾回收机制的意义 java 语言中一个...

  • Java 内存区域和GC机制

    Java垃圾回收概况 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与...

  • JVM垃圾回收机制

    JVM垃圾回收 整体思维导图 带着问题理解JVM垃圾回收机制 Java为什么需要垃圾回收机制; 回收哪部分垃圾; ...

  • java内存结构和GC机制

    Java垃圾回收概况 Java GC(Garbage Collection,垃圾回收)机制,是Java与C++/C...

  • 对 Java 内存的一些理解-[Android_YangKe]

    Java 垃圾回收机制优点 Java 内存模型 什么是内存抖动 什么是内存泄漏 垃圾回收机制常见算法 Java 垃...

  • Android知识大纲

    Android知识大纲 Java垃圾回收机制 Java内存是如何划分的,Java语言为什么要使用垃圾回收机制? 垃...

  • 优秀的程序员更重视阅读源码,不看源码那是假的

    从事Java开发的都知道java有个垃圾回收机制Garbage collection,要准确理解Java的垃圾回收...

  • JavaScript垃圾回收机制

    什么是垃圾回收机制? 和java,c#一样,javascript也有垃圾回收的机制,比如说c++和c就没有垃圾回收...

  • 2020-04-19 垃圾回收机制算法

    垃圾回收机制算法 垃圾回收机制概述 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存...

  • JVM之Java垃圾回收机制

    为大家推荐一篇写的通俗易懂的关于Java垃圾回收机制的文章理解Java垃圾回收机制 Java主要把内存分为堆内存和...

网友评论

      本文标题:Java垃圾回收机制

      本文链接:https://www.haomeiwen.com/subject/jcbovftx.html