JVM-044-垃圾回收-相关概念的概述-内存溢出与内存泄漏

内存溢出(OutOfMemoryError)

概念

  • 内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也是引发程序崩溃的罪魁祸首之一。

  • 由于GC一直在发展,所以一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现OOM的情况。

  • 大多数情况下,GC会进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的Full GC操作,这时候会回收大量的内存,供应用程序继续使用。

  • Javadoc中对OutofMemoryError的解释是,没有空闲内存,并且垃圾收集器也无法提供更多内存。

阅读更多

JVM-043-垃圾回收-相关概念的概述-System.gc()的理解

概念

  • 在默认情况下,通过System.gc()Runtime.getRuntime().gc() 的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。

  • 然而System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用(不能确保立即生效)

  • JVM实现者可以通过System.gc() 调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基本测试,我们可以在运行之间调用System.gc()。

阅读更多

JVM-042-垃圾回收-相关算法-算法使用方式

没有最好的算法,只有最合适的算法

分代收集算法(Generational Collecting)

引入

前面所有这些算法中,并没有一种算法可以完全替代其他算法,它们都具有自己独特的优势和特点。分代收集算法应运而生。分代的思想被现有的虚拟机广泛使用。几乎所有的垃圾回收器都区分新生代和老年代。

阅读更多

JVM-041-垃圾回收-相关算法-清除阶段

引入

当成功区分出内存中存活对象和死亡对象后,GC接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对象分配内存。目前在JVM中比较常见的三种垃圾收集算法是

  1. 标记-清除算法(Mark-Sweep)
  2. 复制算法(Copying)
  3. 标记-压缩算法(Mark-Compact)
阅读更多

JVM-040-垃圾回收-MAT与JProfiler的GC Roots溯源

MAT 介绍

  1. MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器。用于查找内存泄漏以及查看内存消耗情况。
  2. MAT是基于Eclipse开发的,是一款免费的性能分析工具。
  3. 可以在http://www.eclipse.org/mat 下载并使用MAT

为了实时分析GC Roots是哪些东西,中间需要用到一个dump的文件

阅读更多

JVM-039-垃圾回收-对象的finalization机制

概述

  1. Java语言提供了对象终止(finalization)机制来允许开发人员提供对象被销毁之前的自定义处理逻辑
  2. 当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调用这个对象的finalize()方法。
  3. finalize() 方法允许在子类中被重写,用于在对象被回收时进行资源释放。通常在这个方法中进行一些资源释放和清理的工作,比如关闭文件、套接字和数据库连接等。
阅读更多

JVM-038-垃圾回收-相关算法-标记阶段

对象存活判断

在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为垃圾标记阶段

那么在JVM中究竟是如何标记一个死亡对象呢?简单来说,当一个对象已经不再被任何的存活对象继续引用时,就可以宣判为已经死亡。

判断对象存活一般有两种方式:引用计数算法可达性分析算法

阅读更多

JVM-037-垃圾回收-概述

什么是垃圾

  1. 垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
  2. 外文:An object is considered garbage when it can no longer be reached from any pointer in the running program.
  3. 如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序结束,被保留的空间无法被其他对象使用。甚至可能导致内存溢出。
阅读更多

JVM-036-StringTable-intern的使用以及StringTable的垃圾回收

intern()的使用

介绍

翻译:

字符串常量池池最初是空的,由String类私有地维护。在调用intern方法时,如果池中已经包含了由equals(object)方法确定的与该字符串内容相等的字符串,则返回池中的字符串地址。否则,该字符串 对象将被添加到池中,并返回对该字符串对象的地址。

阅读更多