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