1 package org.apache.commons.classscan.util; 2 3 import static org.junit.Assert.assertEquals; 4 import static org.junit.Assert.assertFalse; 5 import static org.junit.Assert.assertNotNull; 6 import static org.junit.Assert.assertNull; 7 import static org.junit.Assert.assertSame; 8 import static org.junit.Assert.assertTrue; 9 10 import java.lang.ref.Reference; 11 import java.lang.ref.ReferenceQueue; 12 import java.lang.ref.WeakReference; 13 import java.util.ArrayList; 14 import java.util.List; 15 16 import org.junit.Test; 17 18 public class ReapingHashMapTest { 19 20 @Test 21 public void testHashWeakReferenceIsCollected() throws InterruptedException { 22 ReferenceQueue<BigObject> queue = new ReferenceQueue<BigObject>(); 23 ReapingHashMap.HashWeakReference<BigObject> hwr = new ReapingHashMap.HashWeakReference<BigObject>(new BigObject(2), queue); 24 assertNotNull(hwr.get()); 25 forceWeakRefCollection(queue, hwr); 26 } 27 28 @Test 29 public void testNullReferenceIsNotCollected() throws InterruptedException { 30 ReferenceQueue<BigObject> queue = new ReferenceQueue<BigObject>(); 31 32 ReapingHashMap.HashWeakReference<BigObject> nullRef = new ReapingHashMap.HashWeakReference<BigObject>(null, queue); 33 assertNull(nullRef.get()); 34 35 ReapingHashMap.HashWeakReference<BigObject> nnRef = new ReapingHashMap.HashWeakReference<BigObject>(new BigObject(2), queue); 36 forceWeakRefCollection(queue, nnRef); 37 38 assertFalse(nullRef.isEnqueued()); 39 assertNull(queue.poll()); 40 } 41 42 @Test(timeout=10000) 43 public void testReapingHashMapIsCollected() throws InterruptedException { 44 ReapingHashMap<BigObject, Integer> rhm = new ReapingHashMap<BigObject, Integer>(); 45 WeakReference<BigObject> key = notReaped(rhm); 46 do { 47 testHashWeakReferenceIsCollected(); 48 } 49 while(key.get()!=null); 50 } 51 52 public WeakReference<BigObject> notReaped(ReapingHashMap<BigObject, Integer> rhm) { 53 BigObject key = new BigObject(2); 54 Integer value = new Integer(2); 55 56 assertNull(rhm.get(null)); 57 assertNull(rhm.get(key)); 58 59 rhm.put(key, value); 60 assertEquals(value, rhm.get(key)); 61 62 Integer nullValue = new Integer(0); 63 rhm.put(null, nullValue); 64 assertEquals(nullValue, rhm.get(null)); 65 66 return new WeakReference<BigObject>(key); 67 } 68 69 static class BigObject { 70 byte[][] lotsOfMemory; 71 72 BigObject(int max) { 73 byte[][] holder= new byte[max][]; 74 int power= 1; 75 for(int i= 0; i<holder.length; ++i) { 76 byte[] bytes= new byte[power]; 77 holder[i]= bytes; 78 power*= 2; 79 } 80 } 81 }; 82 83 public <T> void forceWeakRefCollection(ReferenceQueue<T> queue, WeakReference<T> ref) throws InterruptedException { 84 85 List<BigObject> list = new ArrayList<BigObject>(); 86 for (int i = 0; true; i++) { 87 try { 88 BigObject holder = new BigObject(i); 89 list.add(holder); 90 } catch (OutOfMemoryError oome) { 91 i = 0; 92 } 93 94 if(ref.isEnqueued()) { 95 assertTrue(ref.isEnqueued()); 96 Reference<? extends T> pollRef = queue.remove(1000); 97 assertSame(pollRef, ref); 98 assertEquals(pollRef, ref); 99 assertFalse(ref.isEnqueued()); 100 assertNull(ref.get()); 101 return; 102 } 103 } 104 } 105 }