View Javadoc

1   package net.sf.ehcache;
2   
3   import net.sf.ehcache.config.CacheConfiguration;
4   import net.sf.ehcache.config.Configuration;
5   import net.sf.ehcache.config.MemoryUnit;
6   import net.sf.ehcache.pool.sizeof.AgentSizeOf;
7   import net.sf.ehcache.pool.sizeof.ReflectionSizeOf;
8   import net.sf.ehcache.pool.sizeof.SizeOf;
9   import net.sf.ehcache.pool.sizeof.SizeOfAgent;
10  import net.sf.ehcache.pool.sizeof.UnsafeSizeOf;
11  import net.sf.ehcache.store.Store;
12  import org.junit.Before;
13  import org.junit.Ignore;
14  import org.junit.Test;
15  import org.mockito.internal.matchers.EqualsWithDelta;
16  
17  import java.lang.reflect.Field;
18  import java.util.concurrent.atomic.AtomicLong;
19  
20  import static org.hamcrest.CoreMatchers.is;
21  import static org.junit.Assert.assertThat;
22  
23  /***
24   * @author Alex Snaps
25   */
26  public class PoolCacheManagerTest {
27  
28      @Before
29      public void setup() {
30          getSizeOfEngine().sizeOf("");
31          System.err.println("Testing for a " + System.getProperty("java.version") + " JDK on a "
32                             + System.getProperty("sun.arch.data.model") + "bit VM");
33      }
34  
35      @Ignore
36      @Test
37      public void testOnHeapConsumption() throws Exception {
38          SizeOf sizeOf = getSizeOfEngine();
39          CacheManager cacheManager = new CacheManager(new Configuration().maxBytesLocalHeap(40, MemoryUnit.MEGABYTES));
40          cacheManager.addCache(new Cache(new CacheConfiguration("one", 0).overflowToDisk(false)));
41          cacheManager.addCache(new Cache(new CacheConfiguration("double", 0).overflowToDisk(false)));
42  
43          Cache oneSize = cacheManager.getCache("one");
44          Cache doubleSize = cacheManager.getCache("double");
45  
46          Element test = new Element("test", new Pair("0", new Object()));
47          oneSize.put(test);
48          doubleSize.put(test);
49          sizeOf.deepSizeOf(test);
50          oneSize.remove(test.getKey());
51          int size = 60000;
52          for (int i = 0; i < size; i++) {
53  //            oneSize.put(new Element(i, new Pair(new Object(), new Object())));
54  //            doubleSize.put(new Element(i, new Pair(new Object(), new Object[] {new Object(), new Object()})));
55  //            doubleSize.put(new Element(i + size, new Pair(new Object(), new Object[] {new Object(), new Object()})));
56              doubleSize.put(new Element(new Object(), new Object()));
57  //          doubleSize.put(new Element(i, i + "" + i));
58          }
59          doubleSize.removeAll();
60  
61          long usedBefore = measureMemoryUse();
62  
63          for (int i = 0; i < size; i++) {
64  //            oneSize.put(new Element(i, new Pair(new Object(), new Object())));
65  //            doubleSize.put(new Element(i, new Pair(new Object(), new Object[] {new Object(), new Object()})));
66  //            doubleSize.put(new Element(i + size, new Pair(new Object(), new Object[] {new Object(), new Object()})));
67              oneSize.put(new Element(new Object(), new Object()));
68  //          doubleSize.put(new Element(i, i + "" + i));
69          }
70  
71          long mem = 0;
72          for (Object key : oneSize.getKeys()) {
73              Element element = oneSize.get(key);
74              mem += sizeOf.deepSizeOf(element);
75          }
76          for (Object key : doubleSize.getKeys()) {
77              Element element = doubleSize.get(key);
78              mem += sizeOf.deepSizeOf(element);
79          }
80  
81          assertThat(MemoryUnit.MEGABYTES.toBytes(40) - mem >= 0, is(true));
82          long consumes = measureMemoryUse() - usedBefore;
83          assertThat(consumes +" bytes are actually being used, while we believe " + mem + " are",
84              mem / (float)consumes, new EqualsWithDelta(1f, 0.025f));
85      }
86  
87      private long getInMemorySizeInBytes(final Cache oneSize) throws Exception {
88          Field store = Cache.class.getDeclaredField("compoundStore");
89          store.setAccessible(true);
90          return ((Store) store.get(oneSize)).getInMemorySizeInBytes();
91      }
92  
93      protected long measureMemoryUse() throws InterruptedException {
94          System.gc();
95          Thread.sleep(2000);
96          System.gc();
97          return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
98      }
99  
100     private static final class Pair {
101         private static final AtomicLong counter = new AtomicLong(Long.MIN_VALUE);
102         private final Object one;
103         private final Object two;
104         private final Object oneHidden;
105         private final Object twoHidden;
106         private final Object threeHidden;
107         private final Object fourHidden;
108         private final long instanceNumber;
109 
110         private Pair(final Object one, final Object two) {
111             this.one = one;
112             this.two = two;
113             instanceNumber = counter.getAndIncrement();
114             if(instanceNumber % 4 == 1) {
115                 oneHidden = new Object();
116                 twoHidden = new Object();
117                 threeHidden = new Object();
118                 fourHidden = new Object();
119             } else {
120                 oneHidden = null;
121                 twoHidden = null;
122                 threeHidden = null;
123                 fourHidden = null;
124             }
125         }
126     }
127 
128     private static SizeOf getSizeOfEngine() {
129         try {
130             return new AgentSizeOf();
131         } catch (UnsupportedOperationException e) {
132             try {
133                 return new UnsafeSizeOf();
134             } catch (UnsupportedOperationException f) {
135                 try {
136                     return new ReflectionSizeOf();
137                 } catch (UnsupportedOperationException g) {
138                     throw new CacheException("A suitable SizeOf engine could not be loaded: " + e + ", " + f + ", " + g);
139                 }
140             }
141         }
142     }
143 }