JAVA引用 从零开始的内存释放学习
当计算机内存被过多无用代码占用时,我们可以通过释放内存这种形式来节省java程序运行时所占用的内存。但是,这样就存在一个弊端。因为并不是电脑内存越空旷我们的程序就跑的越快。用简单的方法想,就是你实例化类以后。将该类内存释放,然后内存就空了一块。但是你如果还需要继续使用该类的方法就又要重新实例化该类,所以就需要我们要自己判断需不需要释放掉某个类的内存。
为什么要释放内存?
需要释放内存的原因很简单:大量的已经使用过后无用的代码堆积会导致内存不足并且不在使用的代码会让程序执行效率降低。
因为JVM在执行程序的时候是需要一个一个的查找如果释放掉了一些“无用”的代码则可以在一定程度上增加程序运行效率。
举个例子就是:
假如,我给你一副打乱顺序的扑克牌让你在扑克牌中找到扑克牌中的Joker。但是你不知道Joker在哪只能一张一张的慢慢查找。如果Joker在扑克牌的底部你需要寻找54次才能找到Joker(只是举最简单的递归例子说明)。但是假如我释放掉了一些扑克牌比如J、Q、K这所有花色的这三张丢掉了不用你继续找就算Joker还在底部你也比找一整套扑克牌查找次数要少得多。
首先让我们先来了解下JVM内存的基本知识
首先JAVA的main是一个程序的起点,然后在JVM中申请一大片内存
JVM内存图:
代码:
public class Actionclass{
public static void main(String[] args){
}
}
注:具体详细等讲类加载器时详讲。
因为程序什么都没执行所以main在JVM的中划的内存是空的
如果在main中实例化代码(或调用标准库代码)JVM内存图:
代码:
public class Actionclass{
public static void main(String[] args){
Test t= new Test();
}
}
public class Test{
Test(){
System.out.println(“th’s test”);
}
}
假如当test类执行过后我们不在执行该方法了该方法的存在就是在浪费内存所以就需要我们给释放掉者就用到了我们的引用并且用GC来释放内存;
引用
引用分为:
强引用 Strong References
上面再书写测试代码的时候实例化Test就是强引用等级最高 最强的引用比GC没有办法回收强引用的字段只有在程序结束后给JVM回收掉 宁可程序内存溢出也不会回收【头太铁】
Test t= new Test();//强引用
Sting s = “123”;//强引用
弱引用 Weak Reference
弱引用和强引用正好相反假如强引用相当于GC的亲儿子那么弱引用就相当于GC的老公在外面放荡不羁留下的私生子GC一生气弱引用就滚蛋(只要调用GC弱引用就被释放)
调用方法:
WeakReference<Test> wr =new WeakReference<Test>(new Test());
Wr.get();//返回一个new Test();
实例:
public class Actionclass{
public static void main(String[] args){
WeakReference<Test> wr =new WeakReference<Test>(new Test());
System.out.println(wr.get()==null);
System.gc();//gc来了弱引用该被释放了
System.out.println(wr.get()==null);}
}
public class Test{
}
执行结果:
false
true
软引用 Soft Reference
软引用是GC娘家侄子 在怎么调皮捣蛋只要家里不吃紧(内存还够)就一直存在
和软引用用法一样:
SoftReference<Test> wr =new SoftReference<Test>(new Test());
Wr.get();//返回一个new Test();
实例:
ublic class Actionclass{
public static void main(String[] args){
SoftReference<Test> wr =new SoftReference<Test>(new Test());
System.out.println(wr.get()==null);
System.gc();//gc来了弱引用也不被释放
System.out.println(wr.get()==null);}
}
public class Test{
}
执行结果:
false
false
幻影引用 Phantom Reference(虚引用、影引用等等...)
幻影引用一般用处不大 这个引用就仿佛没有存在(所以才叫幻影吧)实例化后就立马被释放掉了
ReferenceQueue rq = new ReferenceQueue();
PhantomReference<Test> wr =new PhantomReference<Test>(new Test(),rq );
实例:
public class Actionclass{
public static void main(String[] args){
ReferenceQueue rq = new ReferenceQueue();
PhantomReference<Test> wr =new PhantomReference<Test>(new Test(),rq );
System.out.println(wr.get()==null);
}
public class Test{
Test(){
System.out.println(“th’s test”);
}
}
执行结果:
th’s test
true
true