package gcj;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.nio.Buffer;
/* 2017-02-15 09:28:51
*垃圾回收机制
*只负责回收堆内存的对象,不会回收任何物理资源
*
*程序无法精确控制垃圾回收,当对象永久性的是引用,系统就会在合适的时候回收它占有的内存
*
*在回收之前会使用finalize 方法 ,该方法可以是对象复活,导致垃圾回收机制取消
*
*对象在内存中的三种状态
*可达状态
*一个对象被创建后,一个以上的引用变量引用他, 这个对象在程序中处于可达状态,
*
*可恢复状态
* 在程序中某个对象不在有任何引用变量引用他,它就可以进入了可恢复状态
*这种状态下,垃圾回收机制准备回收该对象所占用的内存,回收该对象之前,会调用所有可恢复状态对象的finalize 方法进行资源清理,
*如果系统在调用finalize 方法重新让一个引用变量引用该对象,则这个对象会再次变为可达状态,否则进入不可达状态
*
*
*不可达状态
*对象与所有引用变量的关联都会被切断,且系统已经调用finalize 方法后依然 没有使该对象变成可达状态, 这个对象经永久性的失去引用,变成不可达状态,这时候系统才会真正回收该对象所占有资源
*
*
*强制垃圾回收机制
*
*当一个对象失去引用后,系统何时调用它的finalize 方法对它进行资源清理,何时变成不可达,系统何时回收它所占用的内存,对程序完全透明,
*程序只能控制一个对象何时不再被任何引用变量引用,绝不能控制它何时被回收
*
*无法精确控制java垃圾回收的时机,但依然可以强制系统进行垃圾回收,这种强制只是通知系统进行垃圾回收,但系统是否进行回收,依然不能确定,
*
*强制系统垃圾回收后,总会有一些效果,
*
*强制垃圾回收的两种方式
* system 类的 gc 静态方法 System.gc()
* Runtime 对象的gc 实例方法Runtime.getRuntime().gc()
*
* 将会执行
* java -verbose:gc GcTest 命令来进行强制垃圾回收
*
*
* finalize 方法
*
* 垃圾回收机制之前 ,通常调用finalize 方法来清理支援, 在没有明确指定的情况下,java 提供默认的机制来清理该对象的资源,就是finalize方法
* protected void finalize() throws Throwable
*
* finalize 方法返回后 对象消失 ,垃圾回收机制开始执行
* 方法原型中的throws Throwable 表示可以抛出任何类型的异常
*
*
* 任何类都可以重写 object 类的finalize 方法
*
*
* 永远不要主动调用某个对象的finalize 方法,该方法应交给垃圾回收机制调用
* finalize 方法何时调用 具有不确定性
* 不要把finalize 方法当成一定会被执行的方法
*
* jvm执行可恢复对象的finalize方法时 可能使该对象或系统中其他对象重新变成可达状态
*
* jvm执行 finalize 方法时 出现异常时,垃圾回收机制不会报告异常 程序继续执行
*
*
*
*对象的软、弱、虚引用
*强引用 strongreference 常见的引用方式,程序常见一个对象,并把这个对象赋给一个引用变量,程序通过该引用变量来操作实际的对象
*string str = "" ; 系统会使用常量池来管理这个字符串常量, 会是用强引用来引用 , 系统不会回收这个字符串
*
*
*软引用 softreference
*当一个对象只有软引用时 ,有可能被垃圾回收机制回收,对于软引用 的对象而言, 当系统内存足够时, 它不会被系统回收,程序也可以使用该对象。 系统内存不足时,系统可能回收它
*软引用通常用于对内存敏感的程序中
*
*
*
*弱引用 WeakReference
*
*弱引用级别更低,只有弱引用的对象而言, 当系统垃圾回收机制运行时, 不管内存是否足够,总会回收该对象所占用的内存, 必须等到垃圾回收机制运行时才会被回收
*
*
*虚引用 PhantomReference
*
*虚引用完全类似于没有引用, 虚 引用 对对象本身没有太大影响,对象感觉不到虚引用的存在,它和没有引用的效果大致相同,虚引用 主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,
*虚引用必须和引用队列联合使用
*
* 系统无法通过虚引用来获得被引用的对象 将输出null
* 程序强制垃圾回收收
* 虚引用的对象将会被垃圾回收
* 对应的虚引用将被添加到关联的引用队列中
*
*引用队列有java.lang.ref.ReferenceQueue 类 表示
* 用于保存被回收后对象的引用,当联合使用软引用、弱引用、和引用队列,系统在回收被引用的对象之后,将被回收对象对应的引用添加到关联的引用队列中
* 与软引用和弱引用不同的是,虚引用在对象被释放之前,将把他对应的虚引用添加到它关联的引用队列中,
* 使得可以在对象被回收指引采取行动
*
* 软引用和弱引用可以单独使用,但虚引用不能单独使用,单独使用虚引用没有太大的意义
* 虚引用主要作用就是跟踪对象被垃圾回收状态,程序可以通过检查与虚引用关联的引用队列中是否已经包含了该虚引用,从而了解虚引用所引用的对象是否即将被回收
*
*
*
*引用类可以避免在程序执行期间将对象留在内存中
*如果以软引用、弱引用或虚引用的方法引用对象
*垃圾回收器 就能够随意的释放对象,
*如果希望尽可能的减少程序在其声明周期中所占用的内存大小是时,就可以使用引用类
*
*
*
*
*/
public class State1 {
public static void main(String[] args) throws Exception{
s1();
String string = new String("虚引用");
ReferenceQueue referenceQueue = new ReferenceQueue(); //创建一个引用队列
PhantomReference phantomReference = new PhantomReference(string, referenceQueue); //创建一个虚引用指向 字符串
string = null ; // 切断string的联系
System.out.println(phantomReference.get()); // 不能通过虚引用获得被引用的对象 会输出null
System.gc(); // 强制垃圾回收
System.runFinalization(); // 虚拟引用将被放入引用队列
}
public static void s1() {
String string = new String("java"); //定义一个a变量指向 java 此字符串处于可达状态
string = new String("jdbc"); //再次创建一个字符创对象 jdbc 处于可达状态
System.out.println(string);
}
}