相关术语
-
内存泄露
程序运行时分配出去的内存得不到及时回收就会造成系统运行速度下降,甚至瘫痪,这种情况就叫做内存泄露
-
垃圾回收
回收那些不再使用的内存,被称为垃圾回收(Garbage Collection,GC)
-
JRE
Java运行环境(Java Runtime Environment,简称JRE)
-
JVM
JVM是JavaVirtualMachine(Java虚拟机)的缩写
-
永生代内存
PermGen,永生代内存主要用于存储一些需要常驻内存,通常不会被回收的信息
-
元空间
Metaspace,用来存储类的元数据的内存空间成为元空间
显式垃圾回收的缺点
- 系统忘记及时回收垃圾,导致内存泄露
- 错误的回收核心类库的内存,导致系统崩溃
Java垃圾回收机制
java的内存垃圾是JRE在后台自动进行回收。通常JRE会在后台创建一个后台线程进行检测和控制,一般在CPU空闲或者内存不足时进行垃圾回收,而程序员无法精确控制垃圾回收的时间和顺序。
- 垃圾回收器的工作目标是回收无用对象的内存空间,这些空间都是堆内存中的空间。垃圾回收器只能回收内存资源,对于数据库链接,磁盘IO等无能为力
- 可以为对象赋值为null,使垃圾回收器更快的回收不再使用的对象
- 垃圾回收具有不可预知性,不同的JVM采用了不同的垃圾回收机制,它可能是定时发生的,可能是CPU空闲时发生的,也有可能是内存出现极限消耗时发生的。程序员可以通关Runtime对象的gc或者 System.gc等方法来建议系统进行垃圾回收,但这些建议仅仅是建议,也无法精确控制系统垃圾回收。
- 垃圾回收具有精确性:主要体现在垃圾回收机制可以精确标记活着的对象,并且可以精确的定位对象间的引用关系
- 现在jvm有多种的垃圾回收机制
- 有的在垃圾回收运行时,就停止应用程序的运行
- 有的在垃圾回收运行时,允许应用程序的线程运行
- 有的允许垃圾回收机制多线程运行
垃圾回收器更迭历史
- 2011年7月发布的java7提供了G1垃圾回收器代替原先的标记/清除垃圾回收器(简称CMS)
- 2014年3月发布的java8删除了 HotSpot JVM 中的永生代内存,类的元数据转而被存储到元空间内。
- 2017年9月发布的java9彻底删除了传统的CMS垃圾回收器,因此运行 JVM 的DefNew+CMS,ParNew+SerialOld,Incremental CMS 等组合全部失效.java 命令(该命令负责启用 JVM 运行 Java 程序)以前支持的以下 GC 相关选项全部被删除
垃圾回收机制特征
- 垃圾回收机制只负责回收堆内存中的对象,不会回收任何物理磁盘资源(例如数据库连接,网络 IO 等资源).
- 程序无法精确控制垃圾回收的运行,垃圾回收会在合适的时候进行.当对象永久性地失去引用后,系统就会在合适的时候回收它所占的内存.
- 在垃圾回收机制回收任何对象之前,总会先调用它的 finalize 方法,该方法可能使该对象重新复活(让一个引用变量重新引用该对象),从而导致垃圾回收机制取消回收.
对象在内存中的状态
- 可达状态:当对象在内存中被创建后,有一个以上的引用变量引用他
- 可恢复状态:当对象在内存中没有被任意引用变量引用,且没有被调用finalize方法
- 不可达状态:当对象在内存中没有被任意引用变量引用,且已经执行了finalize方法
强制(伪)垃圾回收
强制垃圾回收的两种方式分别为:
- 调用 System 类的 gc 静态方法:System.gc().
- 调用 Runtime 对象的 gc 实例方法:Runtime.getRuntime().gc().
虽然说是强制垃圾回收,但是我们执行上述方法知识建议系统进行强制回收,可能并不会立即执行,实际回收的时间程序开发者目前无法通过java进行控制,所以说java的强制垃圾回收为伪强制。但是垃圾回收机制也不会对强制回收请求完全置之不理,收到请求后会尽快进行垃圾回收。
通过以下命令可以看到每次垃圾回收后的提示信息
java -verbose:gc 待执行的类
对象的4中引用方式
- 强引用
把对象赋值给至少一个变量。这时对象处于可达状态,垃圾回收机制不会对可达状态的对象进行回收
- 软引用
软引用主要通过SoftReference的方式实现,当一个对象只有软引用时,系统内存足够时他不会被系统回收,但是当系统内部不够时,它可能被系统回收
- 弱引用
弱引用通过WeakReference的方式实现,弱引用和软引用相似,但是系统内存足够时它也被系统回收。并不是说它一创建就会被回收,而是垃圾回收机制运行时它才会被回收。
- 虚引用
虚引用通过PhantomReference的方式实现,虚引用和没有引用基本一样,虚引用主要用来跟踪对象被系统回收的状态。虚引用不能单独使用,必须和和引用队列(Reference)一起使用