内存堆栈的简单解释
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 ReferenceQueuerq = new ReferenceQueue (); public static void checkQueue(){ Reference inq = rq.poll(); if(inq!=null){ System.out.println("In queue : "+inq.get()); } } public static void main(String[] args){ final int size = 10; Set > sa = new HashSet >(); for(int i=0;i ref = new SoftReference (new Grocery("Soft "+i),rq); System.out.println("Just created: "+ref.get()); sa.add(ref); } System.gc(); checkQueue(); Set > wa = new HashSet >(); for(int i=0;i ref = new WeakReference (new Grocery("Weak "+i),rq); System.out.println("Just created: "+ref.get()); wa.add(ref); } System.gc(); checkQueue(); Set > pa = new HashSet >(); for(int i=0;i ref = new PhantomReference (new Grocery("Phantom "+i),rq); System.out.println("Just created: "+ref.get()); pa.add(ref); } System.gc(); checkQueue(); } }
非官方的说法,摘录与网上.仅自己总结用于了解内存结构.