1.javaä¸ä¸ªå¼ç¨ç±»å
javaä¸ä¸ªå¼ç¨ç±»å
åç§å¼ç¨ç±»å
æä»¥å¨ JDK.1.2 ä¹åï¼Java 对å¼ç¨çæ¦å¿µè¿è¡äºæ©å ï¼å°å¼ç¨å为äºï¼å¼ºå¼ç¨ï¼Strong Referenceï¼ã软å¼ç¨ï¼Soft Referenceï¼ãå¼±å¼ç¨ï¼Weak Referenceï¼ãèå¼ç¨ï¼Phantom Referenceï¼4 ç§ï¼è¿ 4 ç§å¼ç¨ç强度ä¾æ¬¡åå¼±ã
ä¸ï¼å¼ºå¼ç¨
Javaä¸é»è®¤å£°æçå°±æ¯å¼ºå¼ç¨ï¼æ¯å¦ï¼
Object obj = new Object(); //åªè¦objè¿æåObject对象ï¼Object对象就ä¸ä¼è¢«åæ¶
obj = null; //æå¨ç½®null
åªè¦å¼ºå¼ç¨åå¨ï¼åå¾åæ¶å¨å°æ°¸è¿ä¸ä¼åæ¶è¢«å¼ç¨ç对象ï¼åªæå åä¸è¶³æ¶ï¼JVMä¹ä¼ç´æ¥æåºOutOfMemoryErrorï¼ä¸ä¼å»åæ¶ãå¦ææ³ä¸æ强å¼ç¨ä¸å¯¹è±¡ä¹é´çèç³»ï¼å¯ä»¥æ¾ç¤ºçå°å¼ºå¼ç¨èµå¼ä¸ºnullï¼è¿æ ·ä¸æ¥ï¼JVMå°±å¯ä»¥éæ¶çåæ¶å¯¹è±¡äº
äºï¼è½¯å¼ç¨
软å¼ç¨æ¯ç¨æ¥æè¿°ä¸äºéå¿ éä½ä»æç¨ç对象ãå¨å å足å¤çæ¶åï¼è½¯å¼ç¨å¯¹è±¡ä¸ä¼è¢«åæ¶ï¼åªæå¨å åä¸è¶³æ¶ï¼ç³»ç»åä¼åæ¶è½¯å¼ç¨å¯¹è±¡ï¼å¦æåæ¶äºè½¯å¼ç¨å¯¹è±¡ä¹åä»ç¶æ²¡æ足å¤çå åï¼æä¼æåºå å溢åºå¼å¸¸ãè¿ç§ç¹æ§å¸¸å¸¸è¢«ç¨æ¥å®ç°ç¼åææ¯ï¼æ¯å¦ç½é¡µç¼åï¼å¾çç¼åçã
å¨ JDK1.2 ä¹åï¼ç¨java.lang.ref.SoftReferenceç±»æ¥è¡¨ç¤ºè½¯å¼ç¨ã
ä¸é¢ä»¥ä¸ä¸ªä¾åæ¥è¿ä¸æ¥è¯´æ强å¼ç¨å软å¼ç¨çåºå«ï¼
å¨è¿è¡ä¸é¢çJava代ç ä¹åï¼éè¦å é ç½®åæ° -Xms2M -Xmx3Mï¼å° JVM çåå§å å设为2Mï¼æ大å¯ç¨å å为 3Mã
é¦å å æ¥æµè¯ä¸ä¸å¼ºå¼ç¨ï¼å¨éå¶äº JVM å åçåæä¸ï¼ä¸é¢ç代ç è¿è¡æ£å¸¸
public class TestOOM {
public static void main(String[] args) {
testStrongReference();
}
private static void testStrongReference() {
// å½ new byte为 1M æ¶ï¼ç¨åºè¿è¡æ£å¸¸
byte[] buff = new byte[ * * 1];
}
}
ä½æ¯å¦ææ们å°
byte[] buff = new byte[ * * 1];
æ¿æ¢ä¸ºå建ä¸ä¸ªå¤§å°ä¸º 2M çåèæ°ç»
byte[] buff = new byte[ * * 2];
åå åä¸å¤ä½¿ç¨ï¼ç¨åºç´æ¥æ¥éï¼å¼ºå¼ç¨å¹¶ä¸ä¼è¢«åæ¶
æ¥çæ¥çä¸ä¸è½¯å¼ç¨ä¼æä»ä¹ä¸ä¸æ ·ï¼å¨ä¸é¢ç示ä¾ä¸è¿ç»åå»ºäº ä¸ªå¤§å°ä¸º 1M çåèæ°ç»ï¼å¹¶èµå¼ç»äºè½¯å¼ç¨ï¼ç¶å循ç¯éåå°è¿äºå¯¹è±¡æå°åºæ¥ã
public class TestOOM {
private static List<Object> list = new ArrayList<>();
public static void main(String[] args) {
testSoftReference();
}
private static void testSoftReference() {
for (int i = 0; i < ; i++) {
byte[] buff = new byte[ * ];
SoftReference<byte[]> sr = new SoftReference<>(buff);
list.add(sr);
}
System.gc(); //主å¨éç¥åå¾åæ¶
for(int i=0; i < list.size(); i++){
Object obj = ((SoftReference) list.get(i)).get();
System.out.println(obj);
}
}
}
æå°ç»æï¼
æ们åç°æ 论循ç¯å建å¤å°ä¸ªè½¯å¼ç¨å¯¹è±¡ï¼æå°ç»ææ»æ¯åªææåä¸ä¸ªå¯¹è±¡è¢«ä¿çï¼å ¶ä»çobjå ¨é½è¢«ç½®ç©ºåæ¶äºã
è¿é就说æäºå¨å åä¸è¶³çæ åµä¸ï¼è½¯å¼ç¨å°ä¼è¢«èªå¨åæ¶ã
å¼å¾æ³¨æçä¸ç¹ ,chromium源码浅析 å³ä½¿æ byte[] buff å¼ç¨æå对象, ä¸ buff æ¯ä¸ä¸ªstrong reference, ä½æ¯ SoftReference sr æåç对象ä»ç¶è¢«åæ¶äºï¼è¿æ¯å 为Javaçç¼è¯å¨åç°äºå¨ä¹åç代ç ä¸, buff å·²ç»æ²¡æ被使ç¨äº, æ以èªå¨è¿è¡äºä¼åã
å¦ææ们å°ä¸é¢ç¤ºä¾ç¨å¾®ä¿®æ¹ä¸ä¸ï¼
private static void testSoftReference() {
byte[] buff = null;
for (int i = 0; i < ; i++) {
buff = new byte[ * ];
SoftReference<byte[]> sr = new SoftReference<>(buff);
list.add(sr);
}
System.gc(); //主å¨éç¥åå¾åæ¶
for(int i=0; i < list.size(); i++){
Object obj = ((SoftReference) list.get(i)).get();
System.out.println(obj);
}
System.out.println("buff: " + buff.toString());
}
å buff ä¼å 为强å¼ç¨çåå¨ï¼èæ æ³è¢«åå¾åæ¶ï¼ä»èæåºOOMçé误ã
å¦æä¸ä¸ªå¯¹è±¡æä¸å©ä¸çå¼ç¨æ¯è½¯å¼ç¨ï¼é£ä¹è¯¥å¯¹è±¡æ¯è½¯å¯åçï¼softly reachableï¼ãåå¾æ¶éå¨å¹¶ä¸åå ¶æ¶éå¼±å¯åç对象ä¸æ ·å°½éå°æ¶é软å¯åç对象ï¼ç¸åï¼å®åªå¨çæ£ âéè¦â å åæ¶ææ¶é软å¯åç对象ã
ä¸ï¼å¼±å¼ç¨
å¼±å¼ç¨çå¼ç¨å¼ºåº¦æ¯è½¯å¼ç¨è¦æ´å¼±ä¸äºï¼æ 论å åæ¯å¦è¶³å¤ï¼åªè¦ JVM å¼å§è¿è¡åå¾åæ¶ï¼é£äºè¢«å¼±å¼ç¨å ³èç对象é½ä¼è¢«åæ¶ãå¨ JDK1.2 ä¹åï¼ç¨ java.lang.ref.WeakReference æ¥è¡¨ç¤ºå¼±å¼ç¨ã
æ们以ä¸è½¯å¼ç¨åæ ·çæ¹å¼æ¥æµè¯ä¸ä¸å¼±å¼ç¨ï¼
private static void testWeakReference() {
for (int i = 0; i < ; i++) {
byte[] buff = new byte[ * ];
WeakReference<byte[]> sr = new WeakReference<>(buff);
list.add(sr);
}
System.gc(); //主å¨éç¥åå¾åæ¶
for(int i=0; i < list.size(); i++){
Object obj = ((WeakReference) list.get(i)).get();
System.out.println(obj);
}
}
æå°ç»æï¼
å¯ä»¥åç°ææ被弱å¼ç¨å ³èç对象é½è¢«åå¾åæ¶äºã
åï¼èå¼ç¨
èå¼ç¨æ¯æå¼±çä¸ç§å¼ç¨å ³ç³»ï¼å¦æä¸ä¸ªå¯¹è±¡ä» ææèå¼ç¨ï¼é£ä¹å®å°±å没æä»»ä½å¼ç¨ä¸æ ·ï¼å®éæ¶å¯è½ä¼è¢«åæ¶ï¼å¨ JDK1.2 ä¹åï¼ç¨ PhantomReference ç±»æ¥è¡¨ç¤ºï¼éè¿æ¥çè¿ä¸ªç±»çæºç ï¼åç°å®åªæä¸ä¸ªæé å½æ°åä¸ä¸ª get() æ¹æ³ï¼èä¸å®ç get() æ¹æ³ä» ä» æ¯è¿åä¸ä¸ªnullï¼ä¹å°±æ¯è¯´å°æ°¸è¿æ æ³éè¿èå¼ç¨æ¥è·å对象ï¼èå¼ç¨å¿ é¡»è¦å ReferenceQueue å¼ç¨éåä¸èµ·ä½¿ç¨ã
public class PhantomReference<T> extends Reference<T> {
/
*** Returns this reference object's referent. Because the referent of a
* phantom reference is always inaccessible, this method always returns
* <code>null</code>.
*
* @return <code>null</code>
*/
public T get() {
return null;
}
public PhantomReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
}
é£ä¹ä¼ å ¥å®çæé æ¹æ³ä¸ç ReferenceQueue åæ¯å¦ä½ä½¿ç¨çå¢ï¼
äºï¼å¼ç¨éåï¼ReferenceQueueï¼
å¼ç¨éåå¯ä»¥ä¸è½¯å¼ç¨ãå¼±å¼ç¨ä»¥åèå¼ç¨ä¸èµ·é å使ç¨ï¼å½åå¾åæ¶å¨åå¤åæ¶ä¸ä¸ªå¯¹è±¡æ¶ï¼å¦æåç°å®è¿æå¼ç¨ï¼é£ä¹å°±ä¼å¨åæ¶å¯¹è±¡ä¹åï¼æè¿ä¸ªå¼ç¨å å ¥å°ä¸ä¹å ³èçå¼ç¨éåä¸å»ãç¨åºå¯ä»¥éè¿å¤æå¼ç¨éåä¸æ¯å¦å·²ç»å å ¥äºå¼ç¨ï¼æ¥å¤æ被å¼ç¨ç对象æ¯å¦å°è¦è¢«åå¾åæ¶ï¼è¿æ ·å°±å¯ä»¥å¨å¯¹è±¡è¢«åæ¶ä¹åéåä¸äºå¿ è¦çæªæ½ã