垃圾回收相关概念


目录
  • System.gc()
  • 内存溢出
  • 内存泄漏
  • Stop The World
  • 垃圾回收的并发和并行
  • 安全点
  • 安全区域
  • 引用
    • 强引用
    • 软引用
    • 弱引用
    • 虚引用
    • 终结器引用(Final reference)

System.gc()

调用该gc方法表明 Java 虚拟机将努力回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间,不能保证一定进行回收。

内存溢出

  1. 内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多、没有空闲内存,最终使得程序运行要用到的内存大于能提供的最大内存。
  2. 没有空闲内存情况
    2.1 Java虚拟机的堆内存设置不够
    2.2 代码中创建了大量大对象,并且长时间不能被垃圾收集器收集
  3. 在OOM之前,通常垃圾收集器会被触发,去清理空间

内存泄漏

  1. 内存泄漏(memory leak)是一种资源泄漏,主因是计算机程序对存储器配置管理失当,失去对一段已分配内存空间的控制,造成程序继续占用已经不再使用的内存空间,或是存储器所存储之对象无法透过执行代码而访问,令内存资源空耗。
  2. 也称作“存储渗漏”。严格来说,只有对象不会再被程序用到了,但是Gc又不能回收他们的情况,才叫内存泄漏。
  3. 实际情况很多时候一些不太好的实践(或疏忽)会导致对象的生命周期变得很长甚至导致OOM,也可以叫做宽泛意义上的“内存泄漏”。
  4. 例子
    4.1 单例的生命周期和应用程序是一样长的,所以单例程序中,如果持有对外部对象的引用的话,那么这个外部对象是不能被回收的,则会导致内存泄漏的产生。
    2.2 数据库连接(dataSourse.getconnection()) ,网络连接(socket)和io连接必须手动close,否则是不能被回收的。

Stop The World

  1. Stop-The-World ,简称STW,指的是GC事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应,有点像卡死的感觉,这个停顿称为STW。
  2. 所有的GC都会有这个事件
  3. 开发中不要用System.gc(),会导致STW的发生

垃圾回收的并发和并行

  1. 并发:指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。多个事情在同一时间段内发生了
  2. 多个事情在同一时间点上发生了。
  3. 垃圾收集器语境
    3.1 并行:多条垃圾线程并行工作,用户线程处于等待状态
    3.2 并发:用户线程与垃圾回收线程同时执行,垃圾回收线程不会影响用户线程

安全点

  1. 程序执行时只能在特定的位置才能定下来GC,这些位置称为"安全点"
  2. 安全点太少会导致GC等待时间过长,太多会导致运行时的性能问题
  3. 如何确保所有线程都在最近安全点?
    3.1 抢先式中断(目前没有虚拟机采用):先中断所有线程,如果还有线程不在安全点,就恢复线程,让线程跑到安全点
    3.2 主动式中断:设置一个中断标志,各个线程运行到safe Point的时候主动轮询这个标志,如果中断标志为真,则将自己进行中断挂起。

安全区域

  1. 安全区域是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始Gc都是安全的。
  2. 当线程运行到safe Region的代码时,首先标识已经进入了Safe Region,如果这段时间内发生Gc,JVM会忽略标识为Safe Region状态的线程;
  3. 当线程即将离开safe Region时,会检查M是否已经完成Gc,如果完成了,则继续运行,否则线程必须等待直到收到可以安全离开Safe Region的信号为止;

引用

强引用

类似于"Object object = new Object()"这样的引用关系,无论任何情况下,只要强引用关系还在,垃圾回收器永远不会被引用的对象

软引用

在系统将要内存溢出时,把被软引用对象列入回收范围进行第二次回收,如果内存还是不够,抛出内存溢出异常

 SoftReference softReference = new SoftReference<>(new Object());
 System.out.println("softReference = " + softReference);

弱引用

弱引用与强引用相对,是指不能确保其引用的对象不会被垃圾回收器回收的引用。一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被回收。被弱引用关联的对象只能生存到下一次垃圾收集发生为止,软引用、弱引用都非常适合来保存那些可有可无的缓存数据。

WeakReference softReference = new WeakReference<>(new Object());

虚引用

  1. 一个对象是否有虚引用的存在,完全不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它和没有引用几乎是一样的,随时都可能被垃圾回收器回收。
  2. 虚引用的应用场景,主要是少量的技术上的使用, 主要用来跟踪对象被垃圾回收器回收的活动。
  3. 它可以用来代替 finalize 方法,保证对象在finalize时不会复活(resurrect)。 这允许对象在一个周期内完成垃圾回收,而不需要等待下一个垃圾回收周期以确保它没有复活。
  4. 第二个用途是来检测对象被回收的具体时间(通过与 ReferenceQueue 对象配合使用),确保其内存空间可用。
  Object o = new Object();
  ReferenceQueue referenceQueue = new ReferenceQueue();
  PhantomReference phantomReference = new PhantomReference(o, referenceQueue);
  o = null;

终结器引用(Final reference)

  1. 它用以实现对象的finalize ()方法,也可以称为终结器引用。
  2. 无需手动编码,其内部配合引用队列使用。
  3. 在GC时,终结器引用入队。由Finalizer线程通过终结器引用找到被引用对象并调用它的finalize ()方法,第二次Gc时才能回收被引用对象。
JVM