Java基础知识学习:垃圾回收机制

目录,更新ing,学习Java的点滴记录

  目录放在这里太长了,附目录链接大家可以自由选择查看--------Java学习目录

垃圾回收机制原理

  1. 介绍
     程序员都了解初始化的重要性,但常常会忘记同样也重要的清理工作.但在使用程序库的时候,把一个对象用完就"弃之不顾"的做法并非总是安全的.当然Java有垃圾回收器负责回收无用对象占据的内存资源.Java 程序员可以将更多的精力放到业务逻辑上而不是内存管理工作上,大大的提高了开发效率。
  2. 内存管理
    Java 的内存管理很大程度指的就是:堆中对象的管理,其中包括对象空间的分配和释
    放。
    对象空间的分配:使用 new 关键字创建对象即可
    对象空间的释放:将对象赋值 null 即可。垃圾回收器将负责回收所有”不可达”对象
    的内存空间。
  3. 垃圾回收过程
     任何一种垃圾回收算法一般要做两件基本事情:
      1)发现无用的对象
      2)回收无用对象占用的内存空间。
     垃圾回收机制保证可以将“无用的对象”进行回收。无用的对象指的就是没有任何变量 引用该对象。Java 的垃圾回收器通过相关算法发现无用对象,并进行清除和整理。

垃圾回收相关算法

  1. 引用计数法
     堆中的每个对象都对应一个引用计数器,当有引用指向这个对象时,引用计数器加1,而当指向该对象的引用失效时(引用变为 null),引用计数器减 1,最后如果该对象的引用计算器的值为 0 时,则 Java 垃圾回收器会认为该对象是无用对象并对其进行回收。优点是算法简单,缺点是“循环引用的无用对象”无法别识别。
    在这里插入图片描述
  2. 引用可达法(根搜索算法)
    程序把所有的引用关系看作一张图,从一个节点 GC ROOT 开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。

垃圾回收中分代机制(年轻代,年老代,永久代)

  1. 分代垃圾回收机制,是基于这样一个事实:不同的对象的生命周期是不一样的。因此, 不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。我们将对象分为三种状态:年轻代、年老代、持久代。同时,将处于不同状态的对象放到堆中不同的区域。 JVM 将堆内存划分为 Eden、Survivor 和 Tenured/Old 空间
    在这里插入图片描述
    Minor GC
      用于清理年轻代区域。Eden 区满了就会触发一次 Minor GC。清理无用对象,将有用对象复制到“Survivor1”、“Survivor2”区中。
    Major GC
      用于清理老年代区域。
    Full GC
      用于清理年轻代、年老代区域。 成本较高,会对系统性能产生影响。
  2. 年轻代
     所有新生成的对象首先都是放在Eden 区。 年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象,对应的是Minor GC,每次 Minor GC 会清理年轻代的内存,算法采用效率较高的复制算法,频繁的操作,但是会浪费内存空间。当“年轻代” 区域存放满对象后,就将对象存放到年老代区域
  3. 年老代
     在年轻代中经历了 N(默认 15)次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。年老代对象越来越多,我们就需要启动 Major GC 和 Full GC(全量回收),来一次大扫除,全面清理年轻代区域和年老代区域。
  4. 永久代
     用于存放静态文件,如 Java 类、方法等。持久代对垃圾回收没有显著影响。JDK7 以前就是“方法区”的一种实现。JDK8 以后已经没有“永久代”了,使用 metaspace 元数据空间和堆替代。
  5. JVM调优和Full GC
     在对 JVM 调优的过程中,很大一部分工作就是对于 Full GC 的调节。有如下原因可能导致发生 Full GC:
      1)年老代(Tenured)被写满
      2)持久代(Perm)被写满
      3)System.gc()被显式调用
      4)上一次 GC 之后 Heap 的各域分配策略动态变化

开发中容易造成内存泄露的操作_垃圾回收知识总结

  1. 容易造成内存泄露的场景
     1)创建大量无用对象
      比如,我们在需要大量拼接字符串时,使用了 String 而不是 StringBuilder。
      在这里插入图片描述
     2)静态集合类的使用
      像 HashMap、Vector、List 等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象 Object 也不能被释放。
     3)各种连接对象(IO流对象,数据库连接对象,网络连接对象)未关闭
      IO 流对象、数据库连接对象、网络连接对象等连接对象属于物理连接,和硬盘或者网络连接,不使用的时候一定要关闭。
     4)监听器的使用不当
      释放对象时,没有删除相应的监听器
  2. 其他注意点
     1)程序员无权调用垃圾回收器
     2)程序员可以调用 System.gc(),该方法只是通知 JVM,并不是运行垃圾回收器。尽量少用,会申请启动 Full GC,成本高,影响系统性能。
     3)finalize 方法,是 Java 提供给程序员用来释放对象或资源的方法,但是尽量少用

猜你喜欢

转载自blog.csdn.net/qq_41649001/article/details/106609192
今日推荐