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