教育改变生活
标题: Java虚拟机—— 垃圾回收(一) [打印本页]
作者: 李玮 时间: 2019-8-2 09:59
标题: Java虚拟机—— 垃圾回收(一)
JVM垃圾回收简介
在JVM提供垃圾回收,将内存空间不在使用的对象进行回收,垃圾回收主要针对堆空间,垃圾回收操作需要消耗一定的资源和时间;
JVM对堆空间进行分区:年轻代、年老代、永久代;
对年轻代的垃圾回收:minor GC
对年轻代和老年代同时作用的GC称为:Full GC
Java中的四种引用
Java 的堆内存和 GC 线程
当我们在 Java 上 new 一个对象的时候,都要在 java heap(堆)上为该对象开辟一块内存,当该对象的引用出作用域失效的时候,那么该对象就会作为 GC 垃圾回收器回收的目标之一。
GC 垃圾回收器是由 JVM 专门的一个线程,叫做垃圾回收线程来实现的,该线程的优先级比较低,因此,如果有的对象不被引用了,GC 是不会及时的回收该对象使用的内存的,但是我们有一种方法,当 GC线程执行的时候,可以让它更快的知道该对象是否能被立即回收,那就是当该对象不再使用的时候,把该对象的引用及时置 null,这样就可以帮助 GC 及时判断该对象不再被使用了,可以立即回收了。
大家都知道,所有的 Java 类都继承自 Object 类,该类里面有一个方法,如下:
在 Java 自定义类里面可以重写 finalize 方法,当对象被 GC 回收之前,会先调用对象的 finalize 方法,释放相关的资源,然后在 GC 的下一个回收周期里面,再把该对象的内存回收掉。
Java 是否存在内存泄露
Java 代码虽然不用我们自己释放对象,而是靠 GC 来回收对象内存,但最起码我们要告诉 GC 这个对象我们不用了,这样 GC 才能在一次垃圾回收周期内回收该对象的资源;
我们应该尽量减少 static 成员对象的定义,由于 static 域的成员在方法区,其生命周期和 Java 进程的生命周期是相等的,而且该 static 成员对象又引用了其他的对象,导致在一个直接引用链或者间接引用链上的所有对象都无法被 GC 回收;
我们自定义一个集合的时候,如果从逻辑上集合的某个对象已经不需要使用了,应该立刻把该对象的引用置为 null,否则会使该对象无法回收,造成内存泄露;内存泄漏以及jmap命令的用法;
还有其他的 I/O 流打开了却未关闭,如 File 打开没有关闭,Socket 打开没有关闭,数据库 Connection,Statement,Resultset 等对象打开,使用完了却没有关闭等等,都会造成内存资源泄露的问题。
如何将对象识别为垃圾:1、引用记数法
对对象添加引用的标识,每对对象增加一个引用,引用标识进行+1操作,减少一个引用,标识-1,当标识为0的时候,说明对象不存在引用可以被回收;
缺点:无法处理对象间相互引用的问题;
2、可达性分析
判断对象是否存活,将堆中对象想象成一棵树,从树根(GC root)开始遍历所有的对象,能到达的称为可用对象,不能到达的称之为垃圾;
GC root一定是可达的,主要有:
虚拟机栈中引用的对象一定是可达的;
本地方法栈中的JNI引用的对象;
方法区中静态属性引用的对象;
方法区中常量引用的对象;
欢迎光临 教育改变生活 (http://bbs.goldoar.com/) |
Powered by Discuz! X3.2 |