View Javadoc

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 }