1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.io;
21
22 import java.io.IOException;
23 import java.lang.management.ManagementFactory;
24 import java.lang.management.RuntimeMXBean;
25 import java.nio.ByteBuffer;
26 import java.util.ArrayList;
27 import java.util.Map;
28 import java.util.TreeMap;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.ConcurrentSkipListMap;
31 import java.util.concurrent.CopyOnWriteArrayList;
32 import java.util.concurrent.CopyOnWriteArraySet;
33 import java.util.concurrent.atomic.AtomicBoolean;
34 import java.util.concurrent.atomic.AtomicInteger;
35 import java.util.concurrent.atomic.AtomicLong;
36 import java.util.concurrent.locks.ReentrantReadWriteLock;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.apache.hadoop.hbase.KeyValue;
41 import org.apache.hadoop.hbase.testclassification.SmallTests;
42 import org.apache.hadoop.hbase.client.Delete;
43 import org.apache.hadoop.hbase.client.Put;
44 import org.apache.hadoop.hbase.io.hfile.BlockCacheKey;
45 import org.apache.hadoop.hbase.io.hfile.LruCachedBlock;
46 import org.apache.hadoop.hbase.io.hfile.LruBlockCache;
47 import org.apache.hadoop.hbase.regionserver.CellSkipListSet;
48 import org.apache.hadoop.hbase.regionserver.DefaultMemStore;
49 import org.apache.hadoop.hbase.regionserver.HRegion;
50 import org.apache.hadoop.hbase.regionserver.HStore;
51 import org.apache.hadoop.hbase.regionserver.TimeRangeTracker;
52 import org.apache.hadoop.hbase.util.ClassSize;
53 import org.junit.BeforeClass;
54 import org.junit.Test;
55 import org.junit.experimental.categories.Category;
56
57 import static org.junit.Assert.assertEquals;
58
59
60
61
62
63 @Category(SmallTests.class)
64 public class TestHeapSize {
65 private static final Log LOG = LogFactory.getLog(TestHeapSize.class);
66
67
68
69
70 @BeforeClass
71 public static void beforeClass() throws Exception {
72
73 RuntimeMXBean b = ManagementFactory.getRuntimeMXBean();
74 LOG.info("name=" + b.getName());
75 LOG.info("specname=" + b.getSpecName());
76 LOG.info("specvendor=" + b.getSpecVendor());
77 LOG.info("vmname=" + b.getVmName());
78 LOG.info("vmversion=" + b.getVmVersion());
79 LOG.info("vmvendor=" + b.getVmVendor());
80 Map<String, String> p = b.getSystemProperties();
81 LOG.info("properties=" + p);
82 }
83
84
85
86
87 @Test
88 public void testNativeSizes() throws IOException {
89 Class<?> cl;
90 long expected;
91 long actual;
92
93
94 cl = ArrayList.class;
95 expected = ClassSize.estimateBase(cl, false);
96 actual = ClassSize.ARRAYLIST;
97 if(expected != actual) {
98 ClassSize.estimateBase(cl, true);
99 assertEquals(expected, actual);
100 }
101
102
103 cl = ByteBuffer.class;
104 expected = ClassSize.estimateBase(cl, false);
105 actual = ClassSize.BYTE_BUFFER;
106 if(expected != actual) {
107 ClassSize.estimateBase(cl, true);
108 assertEquals(expected, actual);
109 }
110
111
112 cl = Integer.class;
113 expected = ClassSize.estimateBase(cl, false);
114 actual = ClassSize.INTEGER;
115 if(expected != actual) {
116 ClassSize.estimateBase(cl, true);
117 assertEquals(expected, actual);
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131 cl = Object.class;
132 expected = ClassSize.estimateBase(cl, false);
133 actual = ClassSize.OBJECT;
134 if(expected != actual) {
135 ClassSize.estimateBase(cl, true);
136 assertEquals(expected, actual);
137 }
138
139
140 cl = TreeMap.class;
141 expected = ClassSize.estimateBase(cl, false);
142 actual = ClassSize.TREEMAP;
143 if(expected != actual) {
144 ClassSize.estimateBase(cl, true);
145 assertEquals(expected, actual);
146 }
147
148
149 cl = String.class;
150 expected = ClassSize.estimateBase(cl, false);
151 actual = ClassSize.STRING;
152 if(expected != actual) {
153 ClassSize.estimateBase(cl, true);
154 assertEquals(expected, actual);
155 }
156
157
158 cl = ConcurrentHashMap.class;
159 expected = ClassSize.estimateBase(cl, false);
160 actual = ClassSize.CONCURRENT_HASHMAP;
161 if(expected != actual) {
162 ClassSize.estimateBase(cl, true);
163 assertEquals(expected, actual);
164 }
165
166
167 cl = ConcurrentSkipListMap.class;
168 expected = ClassSize.estimateBase(cl, false);
169 actual = ClassSize.CONCURRENT_SKIPLISTMAP;
170 if(expected != actual) {
171 ClassSize.estimateBase(cl, true);
172 assertEquals(expected, actual);
173 }
174
175
176 cl = ReentrantReadWriteLock.class;
177 expected = ClassSize.estimateBase(cl, false);
178 actual = ClassSize.REENTRANT_LOCK;
179 if(expected != actual) {
180 ClassSize.estimateBase(cl, true);
181 assertEquals(expected, actual);
182 }
183
184
185 cl = AtomicLong.class;
186 expected = ClassSize.estimateBase(cl, false);
187 actual = ClassSize.ATOMIC_LONG;
188 if(expected != actual) {
189 ClassSize.estimateBase(cl, true);
190 assertEquals(expected, actual);
191 }
192
193
194 cl = AtomicInteger.class;
195 expected = ClassSize.estimateBase(cl, false);
196 actual = ClassSize.ATOMIC_INTEGER;
197 if(expected != actual) {
198 ClassSize.estimateBase(cl, true);
199 assertEquals(expected, actual);
200 }
201
202
203 cl = AtomicBoolean.class;
204 expected = ClassSize.estimateBase(cl, false);
205 actual = ClassSize.ATOMIC_BOOLEAN;
206 if(expected != actual) {
207 ClassSize.estimateBase(cl, true);
208 assertEquals(expected, actual);
209 }
210
211
212 cl = CopyOnWriteArraySet.class;
213 expected = ClassSize.estimateBase(cl, false);
214 actual = ClassSize.COPYONWRITE_ARRAYSET;
215 if(expected != actual) {
216 ClassSize.estimateBase(cl, true);
217 assertEquals(expected, actual);
218 }
219
220
221 cl = CopyOnWriteArrayList.class;
222 expected = ClassSize.estimateBase(cl, false);
223 actual = ClassSize.COPYONWRITE_ARRAYLIST;
224 if(expected != actual) {
225 ClassSize.estimateBase(cl, true);
226 assertEquals(expected, actual);
227 }
228
229
230 cl = TimeRangeTracker.class;
231 expected = ClassSize.estimateBase(cl, false);
232 actual = ClassSize.TIMERANGE_TRACKER;
233 if (expected != actual) {
234 ClassSize.estimateBase(cl, true);
235 assertEquals(expected, actual);
236 }
237
238
239 cl = CellSkipListSet.class;
240 expected = ClassSize.estimateBase(cl, false);
241 actual = ClassSize.CELL_SKIPLIST_SET;
242 if (expected != actual) {
243 ClassSize.estimateBase(cl, true);
244 assertEquals(expected, actual);
245 }
246 }
247
248
249
250
251
252
253
254 @Test
255 public void testSizes() throws IOException {
256 Class<?> cl;
257 long expected;
258 long actual;
259
260
261 cl = KeyValue.class;
262 expected = ClassSize.estimateBase(cl, false);
263 KeyValue kv = new KeyValue();
264 actual = kv.heapSize();
265 if(expected != actual) {
266 ClassSize.estimateBase(cl, true);
267 assertEquals(expected, actual);
268 }
269
270
271 cl = LruBlockCache.class;
272 actual = LruBlockCache.CACHE_FIXED_OVERHEAD;
273 expected = ClassSize.estimateBase(cl, false);
274 if(expected != actual) {
275 ClassSize.estimateBase(cl, true);
276 assertEquals(expected, actual);
277 }
278
279
280
281
282 cl = LruCachedBlock.class;
283 actual = LruCachedBlock.PER_BLOCK_OVERHEAD;
284 expected = ClassSize.estimateBase(cl, false);
285 expected += ClassSize.estimateBase(String.class, false);
286 expected += ClassSize.estimateBase(ByteBuffer.class, false);
287 if(expected != actual) {
288 ClassSize.estimateBase(cl, true);
289 ClassSize.estimateBase(String.class, true);
290 ClassSize.estimateBase(ByteBuffer.class, true);
291 assertEquals(expected, actual);
292 }
293
294
295 cl = DefaultMemStore.class;
296 actual = DefaultMemStore.FIXED_OVERHEAD;
297 expected = ClassSize.estimateBase(cl, false);
298 if(expected != actual) {
299 ClassSize.estimateBase(cl, true);
300 assertEquals(expected, actual);
301 }
302
303
304 actual = DefaultMemStore.DEEP_OVERHEAD;
305 expected = ClassSize.estimateBase(cl, false);
306 expected += (2 * ClassSize.estimateBase(AtomicLong.class, false));
307 expected += ClassSize.estimateBase(AtomicInteger.class, false);
308 expected += (2 * ClassSize.estimateBase(CellSkipListSet.class, false));
309 expected += (2 * ClassSize.estimateBase(ConcurrentSkipListMap.class, false));
310 expected += (2 * ClassSize.estimateBase(TimeRangeTracker.class, false));
311 if (expected != actual) {
312 ClassSize.estimateBase(cl, true);
313 ClassSize.estimateBase(AtomicLong.class, true);
314 ClassSize.estimateBase(AtomicLong.class, true);
315 ClassSize.estimateBase(AtomicInteger.class, true);
316 ClassSize.estimateBase(CellSkipListSet.class, true);
317 ClassSize.estimateBase(CellSkipListSet.class, true);
318 ClassSize.estimateBase(ConcurrentSkipListMap.class, true);
319 ClassSize.estimateBase(ConcurrentSkipListMap.class, true);
320 ClassSize.estimateBase(TimeRangeTracker.class, true);
321 ClassSize.estimateBase(TimeRangeTracker.class, true);
322 assertEquals(expected, actual);
323 }
324
325
326 cl = HStore.class;
327 actual = HStore.FIXED_OVERHEAD;
328 expected = ClassSize.estimateBase(cl, false);
329 if(expected != actual) {
330 ClassSize.estimateBase(cl, true);
331 assertEquals(expected, actual);
332 }
333
334
335 cl = HRegion.class;
336 actual = HRegion.FIXED_OVERHEAD;
337 expected = ClassSize.estimateBase(cl, false);
338 if (expected != actual) {
339 ClassSize.estimateBase(cl, true);
340 assertEquals(expected, actual);
341 }
342
343
344
345 cl = BlockCacheKey.class;
346 actual = BlockCacheKey.FIXED_OVERHEAD;
347 expected = ClassSize.estimateBase(cl, false);
348 if (expected != actual) {
349 ClassSize.estimateBase(cl, true);
350 assertEquals(expected, actual);
351 }
352
353
354
355
356
357
358
359 }
360
361 @Test
362 public void testMutations(){
363 Class<?> cl;
364 long expected;
365 long actual;
366
367 cl = TimeRange.class;
368 actual = ClassSize.TIMERANGE;
369 expected = ClassSize.estimateBase(cl, false);
370 if (expected != actual) {
371 ClassSize.estimateBase(cl, true);
372 assertEquals(expected, actual);
373 }
374
375 byte[] row = new byte[] { 0 };
376 cl = Put.class;
377 actual = new Put(row).MUTATION_OVERHEAD + ClassSize.align(ClassSize.ARRAY);
378 expected = ClassSize.estimateBase(cl, false);
379
380 expected += ClassSize.align(ClassSize.TREEMAP);
381 if (expected != actual) {
382 ClassSize.estimateBase(cl, true);
383 assertEquals(expected, actual);
384 }
385
386 cl = Delete.class;
387 actual = new Delete(row).MUTATION_OVERHEAD + ClassSize.align(ClassSize.ARRAY);
388 expected = ClassSize.estimateBase(cl, false);
389
390 expected += ClassSize.align(ClassSize.TREEMAP);
391 if (expected != actual) {
392 ClassSize.estimateBase(cl, true);
393 assertEquals(expected, actual);
394 }
395 }
396
397 }
398