JVM之垃圾回收的相关概念

JVM之垃圾回收的相关概念



1.System.gc()的理解

  • 调用该方法会触发Full GC。

  • 该方法附带个免责声明,无法保证对垃圾收集器的调用时间,意思就是不是你一调用该方法就进行垃圾回收。

  • 尽量少用,一般在特殊情况下调用,比如性能测试之前。

  • 局部变量表中的数据不会立马失效,而是新来的变量覆盖了这个Slot槽之后 才会被回收。

2.内存溢出

  • 基本解释:

    • 没见有空闲内存,并且垃圾收集器也无法提供更多内存。(GC之后还没有内存)。
    • java虚拟机堆内存不够的原因
      1. Java虚拟机的对内存设置不够。
      2. 代码中创建大量大对象,并且长时间不能被垃圾收集器收集(存在引用)
  • OOM之前,通常垃圾收集器会被触发,尽可能多的清理出空间

    • 尝试回收软引用指向的对象等。
  • 特殊情况下,为一个大对象分配内存超过了堆空间的最大内存,不会进行垃圾回收,直接报OOMError。

3.内存泄漏

  • 严格来说 只有对象不会再被程序用到了,但是GC又不能回收它们的情况,才叫内存泄漏。
  • 内存泄漏可能会导致OOM。
  • 内存泄漏会慢慢的蚕食内存,直到内存被消耗殆尽,最终报OOMError。
  • 内存泄漏的相关例子:
    1.单例模式
    ***单例的声明周期和应用程序一样长 *** ,所以单例程序中,如果持有外部对象的引用,就会造成那个对象一直处于可达,不能被回收,就会导致内存泄漏。
    1. Close的资源未关闭导致内存泄漏
      数据库连接、网络连接、io。

4.什么是STW

  • 概念:

指的是GC事件发生过程中会产生应用程序的停顿。停顿产生时整个应用程序的线程都会被暂停,没有任何响应, 这个停顿就被称为 STW

  • 例子

可达性分析算法中枚举根节点(GC Roots)会导致所有java执行的线程停顿。

  • 分析的时候必须保证在同一个快照中进行,保持一致性
  • 如果出现分析过程中对象引用关系还在不断变化,则分析结果的准确性就无法保证
  • 被STW中断的线程会在GC完成之后回复,(会有上下文切换消耗时间)。
  • 所有的GC都会产生STW,只是暂停时间长短的问题,好的GC就应该尽可能的缩短STW的时间

5.垃圾回收中的并行与并发

  • 并发(Concurrent)
  • 在操作系统中是指一个时间段内几个程序(进程)都处于运行到运行完毕之间,且这几个程序都在同一个处理器运行。
  • 并行并不是真正意义的“同时发生”,而是CPU把一个时间段划分成若干个时间片(几十ms),然后在这几个时间片中来回切换线程或进程,由于CPU处理速度非常快,只要时间间隔处理得当,用户就会感觉几个程序都在同时运行。
    并发时间片
  • 并行Parallel
  • 当系统有一个以上CPU(内核),每个CPU同时执行不同的进程,而且两个进程之间不互相抢占资源,称为并行
  • 适合科学计算,后台处理,等弱交互场景。
    在这里插入图片描述
  • 二者比较
  • 并发,指多个事情在同一个时间段内发生
  • 并行,指多个事情在同一个时间点发生
  • 并发的多个任务之间互相抢占资源。
  • 并行的多个任务之间互不抢占资源。
  • 垃圾回收中的并行(Parallel)

指多条垃圾回收的线程并行工作,用户线程处于等待状态。

  • 并行的垃圾回收有,ParNew、Parallel Scavenge、Parallel Old
  • 垃圾回收中串行(Serial)
  • 单线程执行
  • 如果内存不够,程序暂停执行,启动JVM垃圾回收器进行垃圾回收,垃圾回收完了,程序在启动运行。
  • 垃圾回收中的并发(ConCurrent)
  • 指用户线程和垃圾回收线程同时执行(有可能是并行执行,有可能是并发交替执行),垃圾线程执行回收时不会停顿用户线程。
  • CMS、G1

6.安全点和安全区域

  • 安全点(safePoint)
  • 垃圾回收器只有在特定的位置才进行GC,这些位置就是 “安全点”
  • 安全点的选择很重要,如果太少可能导致GC等待时间太久,然后进行GC的时候STW时间就会增加;如果太多GC就会很频繁,可能会导致运行时的性能问题。
  • 如何在GC发生时,(为了一致性)检查所有线程都跑到最近的安全点停顿下来了?
  • 抢先式中断:(目前没有JVM采用了)
    • 首先中断线程。如果还有线程不在安全点,就恢复线程,让线程跑到安全点。(是其它线程在停,等待这个没有到达安全点的线程跑到安全点么?
  • 主动式中断:
    • 设置一个中断标志,让各个线程运行到SafePoint的时候主动轮询这个标志,如果中断标志为真,则主动将自己中断挂起。
  • 安全区域
  • 指在一段代码片段中,对象的引用不会在发生变化,在这个区域中的任何位置都可以开始GC并且是安全的。

总结

  • 不是执行System.gc()就立马进行垃圾回收的,它只是通知JVM进行垃圾回收,不能保证就立马执行。
  • 内存溢出,就是内存不够用了;内存泄漏,是这块虚拟内存一直有引用指向,垃圾回收器无法对其回收,也没有使用这个引用指向,有点占着茅坑不拉屎的感觉。
  • STW,就是为了保证GC的准确性,只有垃圾回收线程可以运行。在我正在数有多少个垃圾的时候,我在前面数着,你在后面丢着。数的肯定不准。
  • 垃圾回收里的并发有点不一样,它指的是垃圾回收线程和用户线程可以同时执行,但是(线程和线程之间可以并行也可以并发)。
  • 安全点为了保证只有到达某个点你猜能GC,安全区域怕你永远到不了那个点,就把这个点扩大个范围,让你GC
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值