内存堆栈的简单解释
a.为了对内存进行更加有效的管理,所以有了堆和栈. 堆内存地址可能是无序的,栈内存通常会有后进先出的规则(思考方法的执行原理).
b.堆内存:使用new关键词获得的内存,
c.栈内存
1.类的信息(方法信息,以及静态变量)
2. 类实例对象中的定义的变量
示例说明:
ArrayList<String> list = new ArrayList<String>();
此语句执行原理
1.先在堆中分配一块内存空间用于存放new ArrayList<String>()中的内容,并且得到所分配的空间的引用(包含堆的分配信息)
2.在栈中分配一个空间用于存放,刚刚获取到的引用信息.
引用的分为4种类型(也可以理解成4种解决方案):
强引用 被存放在栈中的引用,不会被垃圾回收器回收. 如果一个引用不是强引用,则表示该强引用有可能会被垃圾回收器回收.
软引用(垃圾) 仅会在
OutOfMemoryError抛出之前进行垃圾回收.
弱引用(垃圾) 在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存.
虚引用(垃圾) 在任何时候都可能被垃圾回收器回收
垃圾回收优先级 虚引用 > 弱引用 > 软引用
这里说明一下:
在jdk1.2并未区分引用类型.之所以要为引用区分类型的原因是,可以在不影响垃圾回收规则的前提下,循环利用失效的引用(虚引用/弱引用/软引用, 且通常是用软引用).
场景: 缓存(例如java.lang.ThreadLocal)
软引用/弱引用/徐引用 的使用简单示例
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Set;
class Grocery {
private static final int SIZE=10000;
private double[] d = new double[SIZE];
private String id;
public Grocery(String id) {
this.id = id;
}
public String toString(){
return id;
}
public void finalize(){
System.out.println("Finalizing ... "+id);
}
}
public class References {
private static ReferenceQueue<Grocery> rq = new ReferenceQueue<Grocery>();
public static void checkQueue(){
Reference<? extends Grocery> inq = rq.poll();
if(inq!=null){
System.out.println("In queue : "+inq.get());
}
}
public static void main(String[] args){
final int size = 10;
Set<SoftReference<Grocery>> sa = new HashSet<SoftReference<Grocery>>();
for(int i=0;i<size;i++){
SoftReference<Grocery> ref = new SoftReference<Grocery>(new Grocery("Soft "+i),rq);
System.out.println("Just created: "+ref.get());
sa.add(ref);
}
System.gc();
checkQueue();
Set<WeakReference<Grocery>> wa = new HashSet<WeakReference<Grocery>>();
for(int i=0;i<size;i++){
WeakReference<Grocery> ref = new WeakReference<Grocery>(new Grocery("Weak "+i),rq);
System.out.println("Just created: "+ref.get());
wa.add(ref);
}
System.gc();
checkQueue();
Set<PhantomReference<Grocery>> pa = new HashSet<PhantomReference<Grocery>>();
for(int i=0;i<size;i++) {
PhantomReference<Grocery> ref =
new PhantomReference<Grocery>(new Grocery("Phantom "+i),rq);
System.out.println("Just created: "+ref.get());
pa.add(ref);
}
System.gc();
checkQueue();
}
}
非官方的说法,摘录与网上.仅自己总结用于了解内存结构.