• java-GC


    一  JVM把堆分为很多区,如下图

    新生代:新创建的对象都是用新生代分配内存,Eden空间不足时,触发Minor GC,此时会把存活的对象转义进Survivor区。

    老年代:用于存放经过多次Minor GC之后依然存活的对象,至于多少次呢 (HotSpot虚拟机默认15次,用-XX:MaxTenuringThreshold控制,大于该值进入老年代,但这只是个最大值,并不代表一定是这个值)

    新生代的GC(Minor GC): 新生代通常存活时间短,使用copying算法回收,将Eden和Survivor1(FromSpace)存活的对象复制到Survivor2(ToSpace),然后直接清理掉Eden和Survivor1的空间。

    下一次Minor GC 则把Eden和Survivor2存活的对象复制到 Survivor1,然后直接清理Eden和Survivor2,以此轮流,Survivor两块内存中总有一个是空白的。

    使用空闲指针方式来控制GC,指针保存最后一个分配的对象在新生代区间的位置,当新对象要分配内存时,用于检查空间是否足够。连续分配对象时,对象逐渐从Eden到Survivor再到老年代。

    老年代的GC(Major GC/Full GC):老年代对象存活时间长,比较稳定,因此采用标记(Mark)算法进行回收,所谓标记算法就是扫描出存活的对象,再回收未被标记的对象。

    回收后空间要吗合并,要吗标记出来下次分配,减少内存碎片带来的效率损耗。

    永久代:存放Java中的类和加载类的类加载器本身。

    二  GC的触发时间

    1 程序空闲的时候

    2 手动 system.gc()

    3 java堆内存不够用的时候,会触发,第一次触发GC后内存依然不够用,会第二次触发,如果还不够用,就out of memory

    三 GC回收什么东西

    1  引用计数为空的对象

    2 从GC Root开始搜索,且搜索不到的对象

      跟搜索算法:以一系列名为 GC Root的对象作为起点,从这些节点开始往下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,则就证明此对象是不可用的。

    3 从root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象

    四  GC做什么

    总的来说是删除不使用的对象,腾出内存空间。

    五 容易发生内存泄漏的情况

    1 静态集合类像HashMap、Vector等,特别是如果集合里存了集合或者存了对象而且该对象内有集合。

    2 各种连接,数据库连接,网络连接,IO连接等没有显示调用close关闭,不被GC回收导致内存泄露。

    3 监听器的使用,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。

  • 相关阅读:
    让Editplus自动格式化js、css、html。。。
    超强JavaScript编辑器WebStorm上安装zenCoding
    魔哥Css:背景色透明,内容不透明之终极方法!兼容(不支持ie6)。
    支持二次开发的Zigbee模块(SNAP技术)
    XI Monitor Analysis
    SAP 增强方式
    查找业务对应的IDOC类型(HELP)
    POS DM 学习URL
    IDOC MSGRN
    XI 安装MS SQLSERVER JDBC 驱动
  • 原文地址:https://www.cnblogs.com/hup666/p/10679351.html
Copyright © 2020-2023  润新知