JVM内存和垃圾回收-14.垃圾回收相关概念

1.System.gc()的理解

  • 默认情况下,调用System.gc()Runtime.getRuntime().gc()会显示触发Full GC(对新生代和老年代同时进行回收)
  • 该方法被调用后并不能确保对垃圾回收器的调用,只是提醒垃圾回收器执行GC

2.内存溢出和内存泄漏

  • 内存溢出:没有空闲内存,并且垃圾回收器也无法提供更多内存

    • 导致内存溢出的原因:
      • JVM堆的内存设置不足
      • 代码中创建了大量对象,且因为存在引用所以一直未被垃圾回收器收集
    • 在OOM前通常会触发垃圾回收,但是如果对象过大直接超出堆的最大值,JVM会认为垃圾回收无法处理,直接抛出OOM
  • 内存泄漏:对象不会被使用,但是GC又不能回收这些对象,比如在类中声明了很多静态变量(随着类的消亡而消亡),这些对象的生命周期较长,无法在短期被回收,最终导致了OOM

    • 举例:
      • 单例模式:如果某个单例的对象对另一个对象存在引用的话,由于单例对象中存在静态属性,因为着该单例对象随着程序的结束才会被回收,所以即使另一个对象不被使用,因为存在单例对象的引用,也无法被回收
      • 数据库连接、网络连接(连接会产生许多对象)未进行手动地关闭(调用close方法),需要等到程序结束才会被回收

在这里插入图片描述


3.Stop The World

  • 指在GC时会产生程序的停顿(整个应用程序线程都会暂停)
  • STW是JVM在后台自动发起和自动完成的
  • 可达性分析中因为需要枚举GC Roots,也会产生STW(没停止程序则可能会产生新的根节点)
  • 所有的GC都会产生STW
  • 开发中不要使用System.gc(会导致STW)

4.垃圾回收的并行和并发

  • 操作系统中的并行和并发:

    • 并发:在一个时间段中几个程序处于已启动和运行完毕间,且这些程序都运行在一个CPU上(即CPU把一个时间段划分为几个时间片段,并在这些片段间来回切换)

    在这里插入图片描述

    • 并行:系统有多个CPU,每个进程在一个CPU上运行,进程间不抢占资源,可同时进行

    在这里插入图片描述

    • 对比:
      • 并发指多个任务在同一个时间段内同时发生;并行指多个任务在同一个时间点上同时发生
      • 并发多个任务会抢占资源;并行多个任务不会抢占资源
      • 并发发生在单CPU单核中;并行发生在多CPU或单CPU多核中
  • 垃圾回收的并行核并发:

    • 并行:指多条垃圾回收线程并行工作,但此时用户线程依旧处于等待状态;对应的另一个概念是串形(即单线程执行,如果内存不足则将当前程序暂停,启动JVM垃圾回收器进行GC,等回收完再启动程序)

    在这里插入图片描述

    • 并发:指用户线程和垃圾回收线程同时进行(即垃圾回收线程不会暂停用户线程),当然还是可能为交替执行的

    在这里插入图片描述


5.安全点和安全区域

  • 安全点:程序执行时并不是在任意位置都可以停下来进行GC,只有在特定位置可以,这些位置称为安全点

    • 安全点少则导致GC等待时间长;安全点太多则导致运行时的性能问题(意味着需要不断切换)

    • GC时如果保证所有线程在最近的安全点停顿下来了?

      • 抢先式中断:如果还有线程不在安全点,就恢复线程,让线程执行到安全点
      • 主动式中断:设置一个中断标志,每个线程运行到安全点就轮询该标志(中断标志为真时线程就将自己挂起)
  • 安全区域:在一段代码中,对象的引用关系不发生变化,在这个区域任意位置进行GC都是安全的


6.引用

如果希望描述某些对象(比如缓存):当内存空间足够时,可以将这些对象保留在内存中;如果空间在GC后还是不足,则将这些对象进行抛弃(之前的描述中是考虑没有引用就选择抛弃,不管内存是否足够)

注意:下面处理方式都是针对对象可达情况下的处理方式,对于不可达的即使是强引用也会被回收

6.1 强引用-不回收
  • 最常见的普通对象引用(即A a = new A()),也是默认的引用类型
  • 只要强引用(可达)还存在,JVM宁愿抛出OOM,垃圾回收器永远不会回收被引用的对象(当然如果没被引用或将引用赋值为null,对象还是要被回收的)
  • 该引用是内存泄漏的主要原因之一
6.2 软引用-内存不足即回收
  • 如果将不可达的对象进行回收后依旧内存不足,则会将软引用的对象(依旧可达)进行GC(回收完后还是内存不足就报OOM)
  • 该引用不是内存泄漏的原因(内存不足时该引用的都被回收了,再造成OOM就不是软引用的问题了)
  • 对于内存敏感的缓存会使用该引用,如高速缓存(有空闲空间就保留缓存;不足时会及时清理)
6.3 弱引用-发现即回收
  • 只被弱引用关联的对象(依旧可达)只能生存到下一次GC前。GC时即使内存足够也会被回收(即使还存在弱引用导致对象还是可达的)
  • 与软引用的区别:软引用在GC回收时还要判断内存是否足够;弱引用内存足够也回收,回收更快
6.4 虚引用-对象回收跟踪
  • 无论虚引用是否存在都不会对对象的生命周期造成影响(相当于对象不存在该引用)
  • 无法通过该引用获得对象实例,为对象设置该引用的主要目的是在该对象被GC时可以受到系统通知
  • 该引用必须和引用队列联合使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值