强引用:
package ref;
/**
* 强引用
*
*/
public class StrongReferenceDemo {
public static void main(String[] args) {
Object obj1=new Object();//这样定义是强引用,OOM也不会被gc回收
Object obj2=obj1;//复制的是引用地址
obj1=null;
System.gc();
System.out.println("obj1 \t"+obj1);
System.out.println("obj2 \t"+obj2);
}
}
obj1 null
obj2 java.lang.Object@15db9742
软引用:
package ref;
import java.lang.ref.SoftReference;
/**
* 软引用
*
*/
public class SoftReferenceDemo {
//内存够用,gc不会回收软引用
public static void softRef_Memory_Enough(){
Object obj1=new Object();
SoftReference<Object> reference=new SoftReference<Object>(obj1);//软引用
System.out.println("obj1 \t"+obj1);
System.out.println("reference \t"+reference.get());
obj1=null;
System.gc();
System.out.println("obj1 \t"+obj1);
System.out.println("reference \t"+reference.get());
}
//内存不够用,gc回收软引用
/**
* -Xms5m -Xmx5m -XX:+PrintGCDetails
*/
public static void softRef_Memory_NotEnough(){
Object obj1=new Object();
SoftReference<Object> reference=new SoftReference<Object>(obj1);//软引用
System.out.println("obj1 \t"+obj1);
System.out.println("reference \t"+reference.get());
obj1=null;
try {
byte[] by=new byte[30*1024*1024];
}catch(Throwable e){
e.printStackTrace();
} finally {
System.out.println("obj1 \t"+obj1);
System.out.println("reference \t"+reference.get());
}
}
public static void main(String[] args) {
softRef_Memory_Enough();
System.out.println("=================内存不够软引用GC对象=========================");
softRef_Memory_NotEnough();
}
}
obj1 java.lang.Object@15db9742
reference java.lang.Object@15db9742
[GC (System.gc()) [PSYoungGen: 790K->488K(1536K)] 790K->608K(5632K), 0.3359851 secs] [Times: user=0.00 sys=0.00, real=0.35 secs]
[Full GC (System.gc()) [PSYoungGen: 488K->0K(1536K)] [ParOldGen: 120K->541K(4096K)] 608K->541K(5632K), [Metaspace: 2612K->2612K(1056768K)], 0.0039329 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
obj1 null
reference java.lang.Object@15db9742
=内存不够软引用GC对象=========
obj1 java.lang.Object@6d06d69c
reference java.lang.Object@6d06d69c
[GC (Allocation Failure) [PSYoungGen: 19K->96K(1536K)] 561K->637K(5632K), 0.0003409 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 96K->32K(1536K)] 637K->573K(5632K), 0.0003556 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 32K->0K(1536K)] [ParOldGen: 541K->541K(4096K)] 573K->541K(5632K), [Metaspace: 2613K->2613K(1056768K)], 0.0037741 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] 541K->541K(5632K), 0.0003269 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] [ParOldGen: 541K->528K(4096K)] 541K->528K(5632K), [Metaspace: 2613K->2613K(1056768K)], 0.0045028 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
java.lang.OutOfMemoryError: Java heap space
obj1 null
reference null
at ref.SoftReferenceDemo.softRef_Memory_NotEnough(SoftReferenceDemo.java:33)
at ref.SoftReferenceDemo.main(SoftReferenceDemo.java:46)
Heap
PSYoungGen total 1536K, used 40K [0x00000000ffe00000, 0x0000000100000000, 0x0000000100000000)
eden space 1024K, 3% used [0x00000000ffe00000,0x00000000ffe0a318,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
to space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
ParOldGen total 4096K, used 528K [0x00000000ffa00000, 0x00000000ffe00000, 0x00000000ffe00000)
object space 4096K, 12% used [0x00000000ffa00000,0x00000000ffa84310,0x00000000ffe00000)
Metaspace used 2644K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 281K, capacity 386K, committed 512K, reserved 1048576K
弱引用:
package ref;
import java.lang.ref.WeakReference;
/**
* 弱引用:只要发生gc就会被回收
*
*/
public class WeakReferernceDemo {
public static void main(String[] args) {
Object obj1=new Object();
WeakReference<Object> weakReference=new WeakReference<Object>(obj1);
System.out.println("obj1 \t"+obj1);
System.out.println("weakReference \t"+weakReference.get());
obj1=null;
System.gc();
System.out.println("============================================");
System.out.println("obj1 \t"+obj1);
System.out.println("weakReference \t"+weakReference.get());
}
}
obj1 java.lang.Object@15db9742
weakReference java.lang.Object@15db9742
============================================
obj1 null
weakReference null
弱引用Map
package ref;
import java.util.HashMap;
import java.util.WeakHashMap;
public class WeakHashMapDemo {
public static void main(String[] args) {
myHashmap();
System.out.println("==================================================");
myWeakHashMap();
}
private static void myHashmap() {
HashMap<Integer, String> map =new HashMap<>();
Integer key= new Integer(1);
String value = "myHashmap";
map.put(key, value);
System.out.println(map);
key=null;
System.out.println(map);
System.gc();
System.out.println(map+"\t"+map.size());
}
private static void myWeakHashMap() {
WeakHashMap<Integer, String> map =new WeakHashMap<>();
Integer key= new Integer(100);
String value = "myWeakHashMap";
map.put(key, value);
System.out.println(map);
key=null;
System.out.println(map);
System.gc();
System.out.println(map+"\t"+map.size());
}
}
{1=myHashmap}
{1=myHashmap}
{1=myHashmap} 1
==================================================
{100=myWeakHashMap}
{100=myWeakHashMap}
{} 1
引用对列
package ref;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
/**
* 引用队列
* 在gc之前把要被回收的引用放在引用队列中
* 在队列存在说明已经被GC了起到监控对象的作用。
*
*/
public class ReferenceQueueDemo {
public static void main(String[] args) {
Object o1 = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
WeakReference<Object> weakReference = new WeakReference<>(o1, referenceQueue);
System.out.println("o1 \t"+o1);
System.out.println("weakReference \t"+weakReference.get());
System.out.println("referenceQueue \t"+referenceQueue.poll());
System.out.println("========GC回收后==============================");
o1=null;
System.gc();
try{TimeUnit.SECONDS.sleep(1);}catch (Exception e){e.printStackTrace();}
System.out.println("o1 \t"+o1);
System.out.println("weakReference \t"+weakReference.get());
System.out.println("referenceQueue \t"+referenceQueue.poll());
}
}
o1 java.lang.Object@15db9742
weakReference java.lang.Object@15db9742
referenceQueue null
GC回收后======================
o1 null
weakReference null
referenceQueue java.lang.ref.WeakReference@6d06d69c
虚引用
package ref;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
/**
* 虚引用
* java提供了4中引用类型,在垃圾回收的时候,都有各自的特点。
* ReferenceQueue是用来配合引用工作的,没有ReferenceQueue一样可以运行
*
* 创建引用的时侯可以指定关联的引用队列,当GC释放对象内存的时候,会将引用加到引用队列。
* 如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的而对象的内存被回收之前采取必要的行动。
* 这相当与是i中通知机制。
*
* 当关联的引用队列中有数据的时候,意味引用指向的堆内存的对象被回收,通过这种方式,
* jvm允许我们在对象被销毁后,做一下我们想做的事情。
*
*/
public class PhantomReferenceDemo {
public static void main(String[] args) throws Exception {
Object o1=new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference=new PhantomReference<Object>(o1,referenceQueue);//虚引用
System.out.println("o1 \t"+o1);
System.out.println("phantomReference \t"+phantomReference.get());
System.out.println("referenceQueue \t"+referenceQueue.poll());
System.out.println("======================================");
o1=null;
System.gc();
Thread.sleep(500);
System.out.println("o1 \t"+o1);
System.out.println("phantomReference \t"+phantomReference.get());
System.out.println("referenceQueue \t"+referenceQueue.poll());
}
}
o1 java.lang.Object@15db9742
phantomReference null
referenceQueue null
======================================
o1 null
phantomReference null
referenceQueue java.lang.ref.PhantomReference@6d06d69c
Map<String,SoftReference<Bitmap>> image = new Map<String,SoftReference<Bitmap>>();//内存缓存图片,缓解OOM