JVM 内存回收

java 内存回收参考。

package com.new2.jvm;


import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;


public class JVMtest {
	/*
	 * JVM的垃圾回收机制,是否回收一个对象的标准在于:是否还有变量引用该对象? 只要有引用变量引用该 对像,垃圾回收机制就不会回收它。
	 * (注意:引用变量引用不等于引用变量还会使用该对象,即引用变量以后不会再使用该对象, 但只要该引用变量还在在引用,那么JVM也不会回收此对象。)
	 * 
	 * 对象在内存中的状态:1,可达状态(一个对象被创建,引用变量引用该 对像,有向图中,可以从启始导航到该对象)
	 * 2,可恢复状态(没有引用变量引用的对象,即进入了可恢复状态)。在回收对象之前,系统回调用可恢复状态的对象的finalize()方法进行资源清理,
	 * 如果调用finalize()方法重新让一个以上的引用变量引用该对象,则这个对象进入可达状态,否则进入不可达状态 。
	 * 3,不可达状态(对象所有关联都被切断,且系统调用finalize()方法依然没有使该对象变成可达状态,
	 * 此对象进入永久性的失去引用,最后变成不可达),只有当一个对象进入不可达状态,系统才会真正回收该对象所占有的资源。
	 * 
	 * java.lang.ref包下提供了三个类:softReference(软引用),WeakReference(弱引用),PhantomReference
	 * (虚引用); 1,强引用:创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是强引用。
	 * (被强引用引用的对象是不会被Jvm回收的,即使内存非常紧张,这也是造杨java内存泄漏的主要原因。)
	 * 2,软引用:通过softReference类来实现。 (只有软引用的对象,系统内存足够时,引用对象不会被系统回收,内存紧张,对象会被系统回收)
	 * 3,弱引用:通过WeakReference类来实现。 (当系统垃圾回收机制运行时,不管系统内存足够不足够,引用对象都会被系统回收)
	 * 4,虚引用:PhantomReference类。虚引用的主要作用就是跟踪对象被垃圾回收的状。程序可以检查与虚引用关联的
	 * 引用队列中是否已经包含了指定的虚引用,从而了解虚引有所引用的对象是否即将被回收。
	 * 单独用没有意义,必须和java.lang.ref.ReferenceQueue类一起使用。
	 */


	/*
	 * 强引用: 如果在命令行输入java -Xmx2m -Xms2m JVMtest 强制堆内存只有2m,而创一个100000的数组,
	 * 内存紧张,但对象不会被系统回收 造成错误:OutOfMemoryError
	 */
	/*
	 * public static void main(String[] args) {
	 * 
	 * Person[] people=new Person[100000]; for(int i=0;i<people.length;i++) {
	 * people[i]=new Person("name"+i, 10+i); } System.out.println(people[1]);
	 * System.out.println(people[5]);
	 * 
	 * System.gc(); System.runFinalization();
	 * 
	 * System.out.println(people[1]); System.out.println(people[5]); }
	 */


	/*
	 * 软引用: 系统内存足够时,引用对象不会被系统回收 输出结果: Person [name=name1, age=11] Person
	 * [name=name5, age=15]
	 * 
	 * Person [name=name1, age=11] Person [name=name5, age=15]
	 * 
	 * 内存紧张,对象会被系统回收 在命令行输入java -Xmx2m -Xms2m JVMtest 强制堆内存只有2m,而创一个100000的数组,
	 * 内存紧张,对象会被系统回收
	 * 
	 * 输出:null,null,null,null
	 */
	/*
	 * public static void main(String[] args) { //Person[] people=new
	 * Person[100000];
	 * 
	 * SoftReference<Person>[] people=new SoftReference[100000]; for(int
	 * i=0;i<people.length;i++) { //people[i]=new SoftReference<Person>(new
	 * Person("name"+i, 10+i));
	 * 
	 * } System.out.println(people[1].get());
	 * System.out.println(people[5].get());
	 * 
	 * System.gc(); System.runFinalization();
	 * 
	 * System.out.println(people[1].get()); System.out.println(people[5].get());
	 * }
	 */


	/*
	 * 弱引用
	 *清理前: hello world 清理后输出: null
	 * 
	 */


	/*public static void main(String[] args) {
		String string = new String("hello world");  //s是存储在堆里,
		//String string ="hello world";//这样初始化,string会存在栈里,系统会缓存字符串常量,结果:hello world  ,hello world
		
		WeakReference<String> weakReference = new WeakReference<String>(string);
		string = null;
		System.out.println(weakReference.get());


	//弱引用,只要清理运行,就会被 清
		System.gc();
		System.runFinalization();
		
		System.out.println(weakReference.get());


	}*/
	
	
	/*虚引用
	 * null
     * false
     *======清理后==========
     * true
	 * 
	 * 
	 * 
	 */
	public static void main(String[] args) {
		String string = new String("hello world");  //s是存储在堆里,
		//String string ="hello world";//这样初始化,string会存在栈里,系统会缓存字符串常量,结果:hello world  ,hello world
		
		//创建一个引用队列,
		ReferenceQueue<String>  referenceQueue=new ReferenceQueue<>();
		//把虚引用注册到引用队列中去。
		PhantomReference<String> phantomReference = new PhantomReference<String>(string,referenceQueue);
		
		
		string = null;
		//试图通过虚引用取出引用的对象,程序并不能通过虚引用访问被引的对象,此处输出null
		System.out.println(phantomReference.get());
		
		//没有清理前,引用队列referenceQueue中并没有phantomReference引用的对象,所以输出false
		System.out.println(phantomReference==referenceQueue.poll());


	   //虚引用,只要清理运行,就会被 清
		System.gc();
		System.runFinalization();
		
		System.out.println("======清理后==========");
		//清理后,phantomReference引用的对象被清理,引用队列referenceQueue中有phantomReference引用的对象,所以输出true
		System.out.println(phantomReference==referenceQueue.poll());
  //Returns the next available reference from the queue, removing it in the process.


	}
	
	
	/*
	 * 一个对象可以被一个方法的局部变量引用 ,也可以被其他类的变量引用,或被其它对象的实例变量引用。
	 * 1,当被其他类的变量引用,只有该类被销毁后,该对象才会进入可恢复状态。
	 * 2,被其它对象的实例变量引用,只有当引用该对象的对象被销毁或变成不可达状态后,该对象才会进入可恢复状态。
	 * 
	 */
}


class Person {
	String name;
	int age;


	public Person(String name, int age) {


		this.name = name;
		this.age = age;
	}


	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值