JVM之垃圾回收相关概念概述(上)

154 阅读3分钟

这是我参与更文挑战的第 24 天,活动详情查看: 更文挑战

垃圾回收相关概念概述(上)

1.System.gc()的理解

  • 默认情况下调用System.gc(),会显示的触发Full GC,对老年代和新生代进行垃圾回收,释放被丢弃对象占用的内存。
  • 但是System.gc()无法保证对垃圾收集器的调用。
  • 一般情况下垃圾回收是自动进行的,无需手动调用。

2.内存溢出与内存泄漏

内存溢出(OOM)

在一般情况下,除非应用程序占用的内存的增长速度非常快,造成垃圾回收跟不上内存消耗的速度,否则不太容易出现OOM的情况。JavaDoc对OOM的解释是,没有空闲的内存,并且垃圾收集器也无法提供更多内存。在出现OOM之前一般会伴随一次GC,如果GC无法解决问题才会出现OOM。如果是一个超大对象,超过堆空间的最大值,那么可以直接抛出OOM。

没有空闲内存的原因有两个:

  • Java虚拟机的堆内存设置不够
  • 代码中创建了大量的大对象,并且长期被引用无法被垃圾回收器回收。

内存泄漏(Memory Leak)

严格来说,只有对象不会被程序使用到了,但是GC又不能回收的情况下才能叫做内存泄漏。或者是一些不好的操作导致对象的生命周期变得很长甚至导致OOM,也可以看作是内存泄漏,比如把只有方法内使用的变量定义到全局变量,或者静态的变量。

内存泄漏并不会导致程序立马崩溃,但是一旦发生了内存泄漏,程序中内存就会被逐渐消耗,最终出现OOM。

出现的场景举例:比如单例模式的静态对象,该静态对象的生命周期是和JVM的生命周期相同的,如果这个对象引用到其他对象,那么被引用的对象就算不使用,但是没有及时断开引用,那么这个被引用的对象也不会被回收。又比如需要调用close()方法关闭的资源,如数据库连接、网络连接和IO连接,如果没有手动调用close()方法那么不能被回收。

3.Stop The World

简称STW,指的是GC事件发生的过程中,会产生应用卡顿,感觉整个应用被暂停,没有任何响应。

可达性分析算法中枚举根节点会导致所有Java执行线程停顿:

  • 分析工作必须在一个保证一致性的快照下进行。
  • 一致性指的是在分析期间整个执行系统像冻结在某个时间点上。
  • 如果出现分析过程中对象还在不停的变化,则分析结果的准确性无法保证。

频繁出现STW会让用户感觉卡顿,所以需要减少STW发生。

STW和采用哪个垃圾回收器无关,所有的垃圾回收器都有STW事件。