001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.io; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.lang.management.ManagementFactory; 025import java.lang.management.RuntimeMXBean; 026import java.nio.ByteBuffer; 027import java.util.ArrayList; 028import java.util.LinkedList; 029import java.util.Map; 030import java.util.TreeMap; 031import java.util.concurrent.ConcurrentHashMap; 032import java.util.concurrent.ConcurrentSkipListMap; 033import java.util.concurrent.CopyOnWriteArrayList; 034import java.util.concurrent.CopyOnWriteArraySet; 035import java.util.concurrent.atomic.AtomicBoolean; 036import java.util.concurrent.atomic.AtomicInteger; 037import java.util.concurrent.atomic.AtomicLong; 038import java.util.concurrent.atomic.AtomicReference; 039import java.util.concurrent.locks.ReentrantReadWriteLock; 040import org.apache.hadoop.hbase.HBaseClassTestRule; 041import org.apache.hadoop.hbase.KeyValue; 042import org.apache.hadoop.hbase.client.Delete; 043import org.apache.hadoop.hbase.client.Mutation; 044import org.apache.hadoop.hbase.client.Put; 045import org.apache.hadoop.hbase.io.hfile.BlockCacheKey; 046import org.apache.hadoop.hbase.io.hfile.ExclusiveMemHFileBlock; 047import org.apache.hadoop.hbase.io.hfile.HFileBlock; 048import org.apache.hadoop.hbase.io.hfile.HFileContext; 049import org.apache.hadoop.hbase.io.hfile.LruBlockCache; 050import org.apache.hadoop.hbase.io.hfile.LruCachedBlock; 051import org.apache.hadoop.hbase.io.hfile.SharedMemHFileBlock; 052import org.apache.hadoop.hbase.regionserver.CSLMImmutableSegment; 053import org.apache.hadoop.hbase.regionserver.CellArrayImmutableSegment; 054import org.apache.hadoop.hbase.regionserver.CellArrayMap; 055import org.apache.hadoop.hbase.regionserver.CellSet; 056import org.apache.hadoop.hbase.regionserver.CompactingMemStore; 057import org.apache.hadoop.hbase.regionserver.CompactionPipeline; 058import org.apache.hadoop.hbase.regionserver.DefaultMemStore; 059import org.apache.hadoop.hbase.regionserver.HRegion; 060import org.apache.hadoop.hbase.regionserver.HStore; 061import org.apache.hadoop.hbase.regionserver.ImmutableSegment; 062import org.apache.hadoop.hbase.regionserver.MemStoreCompactor; 063import org.apache.hadoop.hbase.regionserver.MutableSegment; 064import org.apache.hadoop.hbase.regionserver.Segment; 065import org.apache.hadoop.hbase.regionserver.TimeRangeTracker.NonSyncTimeRangeTracker; 066import org.apache.hadoop.hbase.regionserver.TimeRangeTracker.SyncTimeRangeTracker; 067import org.apache.hadoop.hbase.regionserver.throttle.StoreHotnessProtector; 068import org.apache.hadoop.hbase.testclassification.IOTests; 069import org.apache.hadoop.hbase.testclassification.SmallTests; 070import org.apache.hadoop.hbase.util.ClassSize; 071import org.junit.BeforeClass; 072import org.junit.ClassRule; 073import org.junit.Test; 074import org.junit.experimental.categories.Category; 075import org.slf4j.Logger; 076import org.slf4j.LoggerFactory; 077 078/** 079 * Testing the sizing that HeapSize offers and compares to the size given by 080 * ClassSize. 081 */ 082@Category({IOTests.class, SmallTests.class}) 083public class TestHeapSize { 084 085 @ClassRule 086 public static final HBaseClassTestRule CLASS_RULE = 087 HBaseClassTestRule.forClass(TestHeapSize.class); 088 089 private static final Logger LOG = LoggerFactory.getLogger(TestHeapSize.class); 090 // List of classes implementing HeapSize 091 // BatchOperation, BatchUpdate, BlockIndex, Entry, Entry<K,V>, HStoreKey 092 // KeyValue, LruBlockCache, Put, WALKey 093 094 @BeforeClass 095 public static void beforeClass() throws Exception { 096 // Print detail on jvm so we know what is different should below test fail. 097 RuntimeMXBean b = ManagementFactory.getRuntimeMXBean(); 098 LOG.info("name=" + b.getName()); 099 LOG.info("specname=" + b.getSpecName()); 100 LOG.info("specvendor=" + b.getSpecVendor()); 101 LOG.info("vmname=" + b.getVmName()); 102 LOG.info("vmversion=" + b.getVmVersion()); 103 LOG.info("vmvendor=" + b.getVmVendor()); 104 Map<String, String> p = b.getSystemProperties(); 105 LOG.info("properties=" + p); 106 } 107 108 /** 109 * Test our hard-coded sizing of native java objects 110 */ 111 @Test 112 public void testNativeSizes() throws IOException { 113 Class<?> cl; 114 long expected; 115 long actual; 116 117 // ArrayList 118 cl = ArrayList.class; 119 expected = ClassSize.estimateBase(cl, false); 120 actual = ClassSize.ARRAYLIST; 121 if(expected != actual) { 122 ClassSize.estimateBase(cl, true); 123 assertEquals(expected, actual); 124 } 125 126 // ByteBuffer 127 cl = ByteBuffer.class; 128 expected = ClassSize.estimateBase(cl, false); 129 actual = ClassSize.BYTE_BUFFER; 130 if(expected != actual) { 131 ClassSize.estimateBase(cl, true); 132 assertEquals(expected, actual); 133 } 134 135 // Integer 136 cl = Integer.class; 137 expected = ClassSize.estimateBase(cl, false); 138 actual = ClassSize.INTEGER; 139 if(expected != actual) { 140 ClassSize.estimateBase(cl, true); 141 assertEquals(expected, actual); 142 } 143 144 // Map.Entry 145 // Interface is public, all others are not. Hard to size via ClassSize 146// cl = Map.Entry.class; 147// expected = ClassSize.estimateBase(cl, false); 148// actual = ClassSize.MAP_ENTRY; 149// if(expected != actual) { 150// ClassSize.estimateBase(cl, true); 151// assertEquals(expected, actual); 152// } 153 154 // Object 155 cl = Object.class; 156 expected = ClassSize.estimateBase(cl, false); 157 actual = ClassSize.align(ClassSize.OBJECT); 158 if(expected != actual) { 159 ClassSize.estimateBase(cl, true); 160 assertEquals(expected, actual); 161 } 162 163 // TreeMap 164 cl = TreeMap.class; 165 expected = ClassSize.estimateBase(cl, false); 166 actual = ClassSize.TREEMAP; 167 if(expected != actual) { 168 ClassSize.estimateBase(cl, true); 169 assertEquals(expected, actual); 170 } 171 172 // String 173 cl = String.class; 174 expected = ClassSize.estimateBase(cl, false); 175 actual = ClassSize.STRING; 176 if(expected != actual) { 177 ClassSize.estimateBase(cl, true); 178 assertEquals(expected, actual); 179 } 180 181 // ConcurrentHashMap 182 cl = ConcurrentHashMap.class; 183 expected = ClassSize.estimateBase(cl, false); 184 actual = ClassSize.CONCURRENT_HASHMAP; 185 if(expected != actual) { 186 ClassSize.estimateBase(cl, true); 187 assertEquals(expected, actual); 188 } 189 190 // ConcurrentSkipListMap 191 cl = ConcurrentSkipListMap.class; 192 expected = ClassSize.estimateBase(cl, false); 193 actual = ClassSize.CONCURRENT_SKIPLISTMAP; 194 if(expected != actual) { 195 ClassSize.estimateBase(cl, true); 196 assertEquals(expected, actual); 197 } 198 199 // CellArrayMap 200 cl = CellArrayMap.class; 201 expected = ClassSize.estimateBase(cl, false); 202 actual = ClassSize.CELL_ARRAY_MAP; 203 if(expected != actual) { 204 ClassSize.estimateBase(cl, true); 205 assertEquals(expected, actual); 206 } 207 208 // ReentrantReadWriteLock 209 cl = ReentrantReadWriteLock.class; 210 expected = ClassSize.estimateBase(cl, false); 211 actual = ClassSize.REENTRANT_LOCK; 212 if(expected != actual) { 213 ClassSize.estimateBase(cl, true); 214 assertEquals(expected, actual); 215 } 216 217 // AtomicLong 218 cl = AtomicLong.class; 219 expected = ClassSize.estimateBase(cl, false); 220 actual = ClassSize.ATOMIC_LONG; 221 if(expected != actual) { 222 ClassSize.estimateBase(cl, true); 223 assertEquals(expected, actual); 224 } 225 226 // AtomicInteger 227 cl = AtomicInteger.class; 228 expected = ClassSize.estimateBase(cl, false); 229 actual = ClassSize.ATOMIC_INTEGER; 230 if(expected != actual) { 231 ClassSize.estimateBase(cl, true); 232 assertEquals(expected, actual); 233 } 234 235 // AtomicBoolean 236 cl = AtomicBoolean.class; 237 expected = ClassSize.estimateBase(cl, false); 238 actual = ClassSize.ATOMIC_BOOLEAN; 239 if(expected != actual) { 240 ClassSize.estimateBase(cl, true); 241 assertEquals(expected, actual); 242 } 243 244 // CopyOnWriteArraySet 245 cl = CopyOnWriteArraySet.class; 246 expected = ClassSize.estimateBase(cl, false); 247 actual = ClassSize.COPYONWRITE_ARRAYSET; 248 if(expected != actual) { 249 ClassSize.estimateBase(cl, true); 250 assertEquals(expected, actual); 251 } 252 253 // CopyOnWriteArrayList 254 cl = CopyOnWriteArrayList.class; 255 expected = ClassSize.estimateBase(cl, false); 256 actual = ClassSize.COPYONWRITE_ARRAYLIST; 257 if(expected != actual) { 258 ClassSize.estimateBase(cl, true); 259 assertEquals(expected, actual); 260 } 261 262 // SyncTimeRangeTracker 263 cl = SyncTimeRangeTracker.class; 264 expected = ClassSize.estimateBase(cl, false); 265 actual = ClassSize.SYNC_TIMERANGE_TRACKER; 266 if (expected != actual) { 267 ClassSize.estimateBase(cl, true); 268 assertEquals(expected, actual); 269 } 270 271 // NonSyncTimeRangeTracker 272 cl = NonSyncTimeRangeTracker.class; 273 expected = ClassSize.estimateBase(cl, false); 274 actual = ClassSize.NON_SYNC_TIMERANGE_TRACKER; 275 if (expected != actual) { 276 ClassSize.estimateBase(cl, true); 277 assertEquals(expected, actual); 278 } 279 280 // CellSet 281 cl = CellSet.class; 282 expected = ClassSize.estimateBase(cl, false); 283 actual = ClassSize.CELL_SET; 284 if (expected != actual) { 285 ClassSize.estimateBase(cl, true); 286 assertEquals(expected, actual); 287 } 288 } 289 290 /** 291 * Testing the classes that implements HeapSize and are a part of 0.20. 292 * Some are not tested here for example BlockIndex which is tested in 293 * TestHFile since it is a non public class 294 * @throws IOException 295 */ 296 @Test 297 public void testSizes() throws IOException { 298 Class<?> cl; 299 long expected; 300 long actual; 301 302 //KeyValue 303 cl = KeyValue.class; 304 expected = ClassSize.estimateBase(cl, false); 305 KeyValue kv = new KeyValue(); 306 actual = kv.heapSize(); 307 if(expected != actual) { 308 ClassSize.estimateBase(cl, true); 309 assertEquals(expected, actual); 310 } 311 312 //LruBlockCache Overhead 313 cl = LruBlockCache.class; 314 actual = LruBlockCache.CACHE_FIXED_OVERHEAD; 315 expected = ClassSize.estimateBase(cl, false); 316 if(expected != actual) { 317 ClassSize.estimateBase(cl, true); 318 assertEquals(expected, actual); 319 } 320 321 // CachedBlock Fixed Overhead 322 // We really need "deep" sizing but ClassSize does not do this. 323 // Perhaps we should do all these more in this style.... 324 cl = LruCachedBlock.class; 325 actual = LruCachedBlock.PER_BLOCK_OVERHEAD; 326 expected = ClassSize.estimateBase(cl, false); 327 expected += ClassSize.estimateBase(String.class, false); 328 expected += ClassSize.estimateBase(ByteBuffer.class, false); 329 if(expected != actual) { 330 ClassSize.estimateBase(cl, true); 331 ClassSize.estimateBase(String.class, true); 332 ClassSize.estimateBase(ByteBuffer.class, true); 333 assertEquals(expected, actual); 334 } 335 336 // DefaultMemStore Overhead 337 cl = DefaultMemStore.class; 338 actual = DefaultMemStore.FIXED_OVERHEAD; 339 expected = ClassSize.estimateBase(cl, false); 340 if(expected != actual) { 341 ClassSize.estimateBase(cl, true); 342 assertEquals(expected, actual); 343 } 344 345 // DefaultMemStore Deep Overhead 346 actual = DefaultMemStore.DEEP_OVERHEAD; 347 expected = ClassSize.estimateBase(cl, false); 348 if (expected != actual) { 349 ClassSize.estimateBase(cl, true); 350 assertEquals(expected, actual); 351 } 352 353 // CompactingMemStore Deep Overhead 354 cl = CompactingMemStore.class; 355 actual = CompactingMemStore.DEEP_OVERHEAD; 356 expected = ClassSize.estimateBase(cl, false); 357 expected += ClassSize.estimateBase(AtomicBoolean.class, false); 358 expected += ClassSize.estimateBase(AtomicBoolean.class, false); 359 expected += ClassSize.estimateBase(CompactionPipeline.class, false); 360 expected += ClassSize.estimateBase(LinkedList.class, false); //inside CompactionPipeline 361 expected += ClassSize.estimateBase(LinkedList.class, false); //inside CompactionPipeline 362 expected += ClassSize.estimateBase(MemStoreCompactor.class, false); 363 expected += ClassSize.estimateBase(AtomicBoolean.class, false);// inside MemStoreCompactor 364 if (expected != actual) { 365 ClassSize.estimateBase(cl, true); 366 ClassSize.estimateBase(AtomicBoolean.class, true); 367 ClassSize.estimateBase(AtomicBoolean.class, true); 368 ClassSize.estimateBase(CompactionPipeline.class, true); 369 ClassSize.estimateBase(LinkedList.class, true); 370 ClassSize.estimateBase(LinkedList.class, true); 371 ClassSize.estimateBase(MemStoreCompactor.class, true); 372 ClassSize.estimateBase(AtomicBoolean.class, true); 373 assertEquals(expected, actual); 374 } 375 376 // Segment Deep overhead 377 cl = Segment.class; 378 actual = Segment.DEEP_OVERHEAD; 379 expected = ClassSize.estimateBase(cl, false); 380 expected += 2 * ClassSize.estimateBase(AtomicLong.class, false); 381 expected += ClassSize.estimateBase(AtomicReference.class, false); 382 expected += ClassSize.estimateBase(CellSet.class, false); 383 expected += ClassSize.estimateBase(ReentrantReadWriteLock.class, false); 384 if (expected != actual) { 385 ClassSize.estimateBase(cl, true); 386 ClassSize.estimateBase(AtomicLong.class, true); 387 ClassSize.estimateBase(AtomicReference.class, true); 388 ClassSize.estimateBase(CellSet.class, true); 389 ClassSize.estimateBase(ReentrantReadWriteLock.class,true); 390 assertEquals(expected, actual); 391 } 392 393 // MutableSegment Deep overhead 394 cl = MutableSegment.class; 395 actual = MutableSegment.DEEP_OVERHEAD; 396 expected = ClassSize.estimateBase(cl, false); 397 expected += 2 * ClassSize.estimateBase(AtomicLong.class, false); 398 expected += ClassSize.estimateBase(AtomicReference.class, false); 399 expected += ClassSize.estimateBase(CellSet.class, false); 400 expected += ClassSize.estimateBase(ReentrantReadWriteLock.class, false); 401 expected += ClassSize.estimateBase(SyncTimeRangeTracker.class, false); 402 expected += ClassSize.estimateBase(ConcurrentSkipListMap.class, false); 403 expected += ClassSize.estimateBase(AtomicBoolean.class, false); 404 if (expected != actual) { 405 ClassSize.estimateBase(cl, true); 406 ClassSize.estimateBase(AtomicLong.class, true); 407 ClassSize.estimateBase(AtomicLong.class, true); 408 ClassSize.estimateBase(AtomicReference.class, true); 409 ClassSize.estimateBase(CellSet.class, true); 410 ClassSize.estimateBase(ReentrantReadWriteLock.class,true); 411 ClassSize.estimateBase(SyncTimeRangeTracker.class, true); 412 ClassSize.estimateBase(ConcurrentSkipListMap.class, true); 413 ClassSize.estimateBase(AtomicBoolean.class,true); 414 assertEquals(expected, actual); 415 } 416 417 // ImmutableSegments Deep overhead 418 cl = ImmutableSegment.class; 419 actual = ImmutableSegment.DEEP_OVERHEAD; 420 expected = ClassSize.estimateBase(cl, false); 421 expected += 2 * ClassSize.estimateBase(AtomicLong.class, false); 422 expected += ClassSize.estimateBase(AtomicReference.class, false); 423 expected += ClassSize.estimateBase(CellSet.class, false); 424 expected += ClassSize.estimateBase(ReentrantReadWriteLock.class, false); 425 expected += ClassSize.estimateBase(NonSyncTimeRangeTracker.class, false); 426 if (expected != actual) { 427 ClassSize.estimateBase(cl, true); 428 ClassSize.estimateBase(AtomicLong.class, true); 429 ClassSize.estimateBase(AtomicLong.class, true); 430 ClassSize.estimateBase(AtomicReference.class, true); 431 ClassSize.estimateBase(CellSet.class, true); 432 ClassSize.estimateBase(ReentrantReadWriteLock.class,true); 433 ClassSize.estimateBase(NonSyncTimeRangeTracker.class, true); 434 assertEquals(expected, actual); 435 } 436 437 cl = CSLMImmutableSegment.class; 438 actual = CSLMImmutableSegment.DEEP_OVERHEAD_CSLM; 439 expected = ClassSize.estimateBase(cl, false); 440 expected += 2 * ClassSize.estimateBase(AtomicLong.class, false); 441 expected += ClassSize.estimateBase(AtomicReference.class, false); 442 expected += ClassSize.estimateBase(CellSet.class, false); 443 expected += ClassSize.estimateBase(ReentrantReadWriteLock.class, false); 444 expected += ClassSize.estimateBase(NonSyncTimeRangeTracker.class, false); 445 expected += ClassSize.estimateBase(ConcurrentSkipListMap.class, false); 446 if (expected != actual) { 447 ClassSize.estimateBase(cl, true); 448 ClassSize.estimateBase(AtomicLong.class, true); 449 ClassSize.estimateBase(AtomicLong.class, true); 450 ClassSize.estimateBase(AtomicReference.class, true); 451 ClassSize.estimateBase(CellSet.class, true); 452 ClassSize.estimateBase(ReentrantReadWriteLock.class,true); 453 ClassSize.estimateBase(NonSyncTimeRangeTracker.class, true); 454 ClassSize.estimateBase(ConcurrentSkipListMap.class, true); 455 assertEquals(expected, actual); 456 } 457 cl = CellArrayImmutableSegment.class; 458 actual = CellArrayImmutableSegment.DEEP_OVERHEAD_CAM; 459 expected = ClassSize.estimateBase(cl, false); 460 expected += 2 * ClassSize.estimateBase(AtomicLong.class, false); 461 expected += ClassSize.estimateBase(AtomicReference.class, false); 462 expected += ClassSize.estimateBase(CellSet.class, false); 463 expected += ClassSize.estimateBase(ReentrantReadWriteLock.class, false); 464 expected += ClassSize.estimateBase(NonSyncTimeRangeTracker.class, false); 465 expected += ClassSize.estimateBase(CellArrayMap.class, false); 466 if (expected != actual) { 467 ClassSize.estimateBase(cl, true); 468 ClassSize.estimateBase(AtomicLong.class, true); 469 ClassSize.estimateBase(AtomicLong.class, true); 470 ClassSize.estimateBase(AtomicReference.class, true); 471 ClassSize.estimateBase(CellSet.class, true); 472 ClassSize.estimateBase(ReentrantReadWriteLock.class,true); 473 ClassSize.estimateBase(NonSyncTimeRangeTracker.class, true); 474 ClassSize.estimateBase(CellArrayMap.class, true); 475 assertEquals(expected, actual); 476 } 477 478 // Store Overhead 479 cl = HStore.class; 480 actual = HStore.FIXED_OVERHEAD; 481 expected = ClassSize.estimateBase(cl, false); 482 if(expected != actual) { 483 ClassSize.estimateBase(cl, true); 484 assertEquals(expected, actual); 485 } 486 487 // Region Overhead 488 cl = HRegion.class; 489 actual = HRegion.FIXED_OVERHEAD; 490 expected = ClassSize.estimateBase(cl, false); 491 if (expected != actual) { 492 ClassSize.estimateBase(cl, true); 493 assertEquals(expected, actual); 494 } 495 496 cl = StoreHotnessProtector.class; 497 actual = StoreHotnessProtector.FIXED_SIZE; 498 expected = ClassSize.estimateBase(cl, false); 499 if (expected != actual) { 500 ClassSize.estimateBase(cl, true); 501 assertEquals(expected, actual); 502 } 503 504 // Block cache key overhead. Only tests fixed overhead as estimating heap 505 // size of strings is hard. 506 cl = BlockCacheKey.class; 507 actual = BlockCacheKey.FIXED_OVERHEAD; 508 expected = ClassSize.estimateBase(cl, false); 509 if (expected != actual) { 510 ClassSize.estimateBase(cl, true); 511 assertEquals(expected, actual); 512 } 513 514 // Currently NOT testing Deep Overheads of many of these classes. 515 // Deep overheads cover a vast majority of stuff, but will not be 100% 516 // accurate because it's unclear when we're referencing stuff that's already 517 // accounted for. But we have satisfied our two core requirements. 518 // Sizing is quite accurate now, and our tests will throw errors if 519 // any of these classes are modified without updating overhead sizes. 520 } 521 522 @Test 523 public void testHFileBlockSize() throws IOException { 524 long expected; 525 long actual; 526 527 actual = HFileContext.FIXED_OVERHEAD; 528 expected = ClassSize.estimateBase(HFileContext.class, false); 529 assertEquals(expected, actual); 530 531 actual = HFileBlock.FIXED_OVERHEAD; 532 expected = ClassSize.estimateBase(HFileBlock.class, false); 533 assertEquals(expected, actual); 534 535 actual = ExclusiveMemHFileBlock.FIXED_OVERHEAD; 536 expected = ClassSize.estimateBase(ExclusiveMemHFileBlock.class, false); 537 assertEquals(expected, actual); 538 539 actual = SharedMemHFileBlock.FIXED_OVERHEAD; 540 expected = ClassSize.estimateBase(SharedMemHFileBlock.class, false); 541 assertEquals(expected, actual); 542 } 543 544 @Test 545 public void testMutations(){ 546 Class<?> cl; 547 long expected; 548 long actual; 549 550 cl = TimeRange.class; 551 actual = ClassSize.TIMERANGE; 552 expected = ClassSize.estimateBase(cl, false); 553 if (expected != actual) { 554 ClassSize.estimateBase(cl, true); 555 assertEquals(expected, actual); 556 } 557 558 byte[] row = new byte[] { 0 }; 559 cl = Put.class; 560 actual = Mutation.MUTATION_OVERHEAD + ClassSize.align(ClassSize.ARRAY); 561 expected = ClassSize.estimateBase(cl, false); 562 //The actual TreeMap is not included in the above calculation 563 expected += ClassSize.align(ClassSize.TREEMAP); 564 expected += ClassSize.align(ClassSize.INTEGER); // priority 565 if (expected != actual) { 566 ClassSize.estimateBase(cl, true); 567 assertEquals(expected, actual); 568 } 569 570 cl = Delete.class; 571 actual = Mutation.MUTATION_OVERHEAD + ClassSize.align(ClassSize.ARRAY); 572 expected = ClassSize.estimateBase(cl, false); 573 //The actual TreeMap is not included in the above calculation 574 expected += ClassSize.align(ClassSize.TREEMAP); 575 expected += ClassSize.align(ClassSize.INTEGER); // priority 576 if (expected != actual) { 577 ClassSize.estimateBase(cl, true); 578 assertEquals(expected, actual); 579 } 580 } 581 582 @Test 583 public void testReferenceSize() { 584 LOG.info("ClassSize.REFERENCE is " + ClassSize.REFERENCE); 585 // oop should be either 4 or 8 586 assertTrue(ClassSize.REFERENCE == 4 || ClassSize.REFERENCE == 8); 587 } 588 589 @Test 590 public void testObjectSize() throws IOException { 591 LOG.info("header:" + ClassSize.OBJECT); 592 LOG.info("array header:" + ClassSize.ARRAY); 593 594 if (ClassSize.is32BitJVM()) { 595 assertEquals(ClassSize.OBJECT, 8); 596 } else { 597 assertTrue(ClassSize.OBJECT == 12 || ClassSize.OBJECT == 16); // depending on CompressedOops 598 } 599 if (ClassSize.useUnsafeLayout()) { 600 assertEquals(ClassSize.ARRAY, ClassSize.OBJECT + 4); 601 } else { 602 assertEquals(ClassSize.ARRAY, ClassSize.OBJECT + 8); 603 } 604 } 605 606 @Test 607 public void testAutoCalcFixedOverHead() { 608 Class[] classList = new Class[] { HFileContext.class, HRegion.class, BlockCacheKey.class, 609 HFileBlock.class, HStore.class, LruBlockCache.class }; 610 for (Class cl : classList) { 611 // do estimate in advance to ensure class is loaded 612 ClassSize.estimateBase(cl, false); 613 614 long startTime = System.currentTimeMillis(); 615 ClassSize.estimateBase(cl, false); 616 long endTime = System.currentTimeMillis(); 617 assertTrue(endTime - startTime < 5); 618 } 619 } 620}