That’s just brilliant!
http://thedailywtf.com/Articles/Disgruntled-Bomb-Java-Edition.aspx
//DL
What is PhantomReference?
Read more about references here: http://www.ibm.com/developerworks/library/j-refs/
See example in Email application in Android platform: http://google.com/codesearch/p?hl=en#SS2by_AKaLs/src/org/apache/commons/io/FileCleaningTracker.java
Btw, you can also ressurect object with reflection (http://code-o-matic.blogspot.com/2009/01/subtleties-of-phantomreference-and.html)
Here’re small exaple of usage:
import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.reflect.Field; import java.util.ArrayList; public class MemoryTest { private ReferenceQueue<Data> mQueue = new ReferenceQueue<Data>(); private boolean mIsRun = true; public void test() { final ArrayList<PhantomReference<Data>> blocks = new ArrayList<PhantomReference<Data>>(); ArrayList<Data> dataArray = new ArrayList<Data>(); System.out.println("occupied mem 1 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); for (int i = 0; i < 10; i++) { Data data = new Data(i); PhantomReference<Data> ref = new PhantomReference<Data>(data, mQueue); blocks.add(ref); dataArray.add(data); } System.out.println("occupied mem 2 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); System.out.println("remove strong ref to object 0 and 1"); dataArray.remove(0); dataArray.remove(0); new Thread() { public void run() { System.out.println("thread started"); while (mIsRun) { Reference<?> ref = null; try { ref = mQueue.remove(1000); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } if (ref != null) { System.out.println(">> removed ref = " + ref); blocks.remove(ref); Field f = null; try { f = Reference.class.getDeclaredField("referent"); f.setAccessible(true); System.out.println("I see dead objects! --> " + f.get(ref)); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } System.out.println("thread ended"); } }.start(); System.out.println("objects created"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("occupied mem 2 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); System.out.println("run gc() to make object enqueued"); System.gc(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("collect memory"); System.runFinalization(); System.gc(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("occupied mem 4 = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); mIsRun = false; } private static class Data { int id; byte[] memoryBlock = new byte[1048576]; public Data(int id) { this.id = id; System.out.println("Data created: " + this); } @Override public String toString() { return "{id=" + id + " " + super.toString() + "}"; } } }
What we can see in LogCat:
06-08 14:38:51.154: INFO/System.out(1385): occupied mem 1 = 2186800 06-08 14:38:51.254: DEBUG/dalvikvm(1385): GC freed 845 objects / 56288 bytes in 94ms 06-08 14:38:51.295: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 4.119MB for 1048592-byte allocation 06-08 14:38:51.394: DEBUG/dalvikvm(1385): GC freed 11 objects / 544 bytes in 93ms 06-08 14:38:51.404: INFO/System.out(1385): Data created: {id=0 com.gtug.test.MemoryTest$Data@4373e658} 06-08 14:38:51.484: DEBUG/dalvikvm(1385): GC freed 22 objects / 1456 bytes in 80ms 06-08 14:38:51.534: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 5.119MB for 1048592-byte allocation 06-08 14:38:51.724: DEBUG/dalvikvm(1385): GC freed 159 objects / 7136 bytes in 191ms 06-08 14:38:51.734: INFO/System.out(1385): Data created: {id=1 com.gtug.test.MemoryTest$Data@4372b7e8} 06-08 14:38:51.825: DEBUG/dalvikvm(1385): GC freed 20 objects / 1352 bytes in 92ms 06-08 14:38:51.865: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 6.112MB for 1048592-byte allocation 06-08 14:38:51.965: DEBUG/dalvikvm(1385): GC freed 36 objects / 18336 bytes in 96ms 06-08 14:38:51.974: INFO/System.out(1385): Data created: {id=2 com.gtug.test.MemoryTest$Data@43734338} 06-08 14:38:52.054: DEBUG/dalvikvm(1385): GC freed 20 objects / 1344 bytes in 87ms 06-08 14:38:52.105: INFO/dalvikvm-heap(1385): Grow heap (frag case) to 7.112MB for 1048592-byte allocation 06-08 14:38:52.204: DEBUG/dalvikvm(1385): GC freed 0 objects / 0 bytes in 98ms 06-08 14:38:52.214: INFO/System.out(1385): Data created: {id=3 com.gtug.test.MemoryTest$Data@4372a968} 06-08 14:38:52.285: INFO/System.out(1385): Data created: {id=4 com.gtug.test.MemoryTest$Data@4372a498} 06-08 14:38:52.375: DEBUG/dalvikvm(1385): GC freed 44 objects / 2888 bytes in 92ms 06-08 14:38:52.455: INFO/System.out(1385): Data created: {id=5 com.gtug.test.MemoryTest$Data@43736180} 06-08 14:38:52.565: DEBUG/dalvikvm(1385): GC freed 25 objects / 1464 bytes in 102ms 06-08 14:38:52.635: INFO/System.out(1385): Data created: {id=6 com.gtug.test.MemoryTest$Data@4372b950} 06-08 14:38:52.755: DEBUG/dalvikvm(1385): GC freed 28 objects / 1584 bytes in 116ms 06-08 14:38:52.804: INFO/ActivityManager(578): Displayed activity com.gtug.test/.PhantomTest: 2327 ms 06-08 14:38:52.875: INFO/System.out(1385): Data created: {id=7 com.gtug.test.MemoryTest$Data@4373b680} 06-08 14:38:53.065: DEBUG/dalvikvm(1385): GC freed 26 objects / 1600 bytes in 179ms 06-08 14:38:53.104: INFO/System.out(1385): Data created: {id=8 com.gtug.test.MemoryTest$Data@437381a8} 06-08 14:38:53.185: DEBUG/dalvikvm(1385): GC freed 24 objects / 1504 bytes in 74ms 06-08 14:38:53.224: INFO/System.out(1385): Data created: {id=9 com.gtug.test.MemoryTest$Data@4373aec8} 06-08 14:38:53.235: INFO/System.out(1385): occupied mem 2 = 12600240 06-08 14:38:53.235: INFO/System.out(1385): remove strong ref to object 0 and 1 06-08 14:38:53.244: INFO/System.out(1385): thread started 06-08 14:38:53.244: INFO/System.out(1385): objects created 06-08 14:38:56.254: INFO/System.out(1385): run gc() -> overrided finalyze print 06-08 14:38:56.324: DEBUG/dalvikvm(1385): GC freed 45 objects / 2512 bytes in 74ms 06-08 14:38:56.334: INFO/System.out(1385): Data finalized: {id=1 com.gtug.test.MemoryTest$Data@4372b7e8} 06-08 14:38:56.334: INFO/System.out(1385): Data finalized: {id=0 com.gtug.test.MemoryTest$Data@4373e658} 06-08 14:38:58.184: DEBUG/dalvikvm(622): GC freed 119 objects / 5872 bytes in 79ms 06-08 14:38:59.344: INFO/System.out(1385): occupied mem 3 = 12602504 06-08 14:38:59.344: INFO/System.out(1385): run gc() second time to make object enqueued 06-08 14:38:59.434: DEBUG/dalvikvm(1385): GC freed 45 objects / 2944 bytes in 85ms 06-08 14:38:59.434: INFO/System.out(1385): >> removed ref = java.lang.ref.PhantomReference@4373a4c0 06-08 14:38:59.434: INFO/System.out(1385): I see dead objects! --> {id=1 com.gtug.test.MemoryTest$Data@4372b7e8} 06-08 14:38:59.434: INFO/System.out(1385): >> removed ref = java.lang.ref.PhantomReference@437343f8 06-08 14:38:59.434: INFO/System.out(1385): I see dead objects! --> {id=0 com.gtug.test.MemoryTest$Data@4373e658} 06-08 14:39:02.446: INFO/System.out(1385): collect memory 06-08 14:39:02.524: DEBUG/dalvikvm(1385): GC freed 75 objects / 2101968 bytes in 76ms 06-08 14:39:07.554: INFO/System.out(1385): occupied mem 4 = 10503728 06-08 14:39:08.454: INFO/System.out(1385): thread ended<!--more-->
happy coding!
//DL
© 2019 Android Tales
Theme by Anders Noren — Up ↑