/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.lucene.util; import static org.apache.lucene.util.RamUsageEstimator.*; import static org.apache.lucene.util.RamUsageTester.sizeOf; import java.util.Random; public class TestRamUsageEstimator extends LuceneTestCase { public void testSanity() { assertTrue(sizeOf("test string") > shallowSizeOfInstance(String.class)); Holder holder = new Holder(); holder.holder = new Holder("string2", 5000L); assertTrue(sizeOf(holder) > shallowSizeOfInstance(Holder.class)); assertTrue(sizeOf(holder) > sizeOf(holder.holder)); assertTrue( shallowSizeOfInstance(HolderSubclass.class) >= shallowSizeOfInstance(Holder.class)); assertTrue( shallowSizeOfInstance(Holder.class) == shallowSizeOfInstance(HolderSubclass2.class)); String[] strings = new String[] { "test string", "hollow", "catchmaster" }; assertTrue(sizeOf(strings) > shallowSizeOf(strings)); } public void testStaticOverloads() { Random rnd = random(); { byte[] array = new byte[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { boolean[] array = new boolean[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { char[] array = new char[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { short[] array = new short[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { int[] array = new int[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { float[] array = new float[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { long[] array = new long[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } { double[] array = new double[rnd.nextInt(1024)]; assertEquals(sizeOf(array), sizeOf((Object) array)); } } public void testReferenceSize() { assertTrue(NUM_BYTES_OBJECT_REF == 4 || NUM_BYTES_OBJECT_REF == 8); if (Constants.JRE_IS_64BIT) { assertEquals("For 64 bit JVMs, reference size must be 8, unless compressed references are enabled", COMPRESSED_REFS_ENABLED ? 4 : 8, NUM_BYTES_OBJECT_REF); } else { assertEquals("For 32bit JVMs, reference size must always be 4", 4, NUM_BYTES_OBJECT_REF); assertFalse("For 32bit JVMs, compressed references can never be enabled", COMPRESSED_REFS_ENABLED); } } public void testHotspotBean() { assumeTrue("testHotspotBean only works on 64bit JVMs.", Constants.JRE_IS_64BIT); try { Class.forName(MANAGEMENT_FACTORY_CLASS); } catch (ClassNotFoundException e) { assumeNoException("testHotspotBean does not work on Java 8+ compact profile.", e); } try { Class.forName(HOTSPOT_BEAN_CLASS); } catch (ClassNotFoundException e) { assumeNoException("testHotspotBean only works on Hotspot (OpenJDK, Oracle) virtual machines.", e); } assertTrue("We should have been able to detect Hotspot's internal settings from the management bean.", JVM_IS_HOTSPOT_64BIT); } /** Helper to print out current settings for debugging {@code -Dtests.verbose=true} */ public void testPrintValues() { assumeTrue("Specify -Dtests.verbose=true to print constants of RamUsageEstimator.", VERBOSE); System.out.println("JVM_IS_HOTSPOT_64BIT = " + JVM_IS_HOTSPOT_64BIT); System.out.println("COMPRESSED_REFS_ENABLED = " + COMPRESSED_REFS_ENABLED); System.out.println("NUM_BYTES_OBJECT_ALIGNMENT = " + NUM_BYTES_OBJECT_ALIGNMENT); System.out.println("NUM_BYTES_OBJECT_REF = " + NUM_BYTES_OBJECT_REF); System.out.println("NUM_BYTES_OBJECT_HEADER = " + NUM_BYTES_OBJECT_HEADER); System.out.println("NUM_BYTES_ARRAY_HEADER = " + NUM_BYTES_ARRAY_HEADER); System.out.println("LONG_SIZE = " + LONG_SIZE); System.out.println("LONG_CACHE_MIN_VALUE = " + LONG_CACHE_MIN_VALUE); System.out.println("LONG_CACHE_MAX_VALUE = " + LONG_CACHE_MAX_VALUE); } @SuppressWarnings("unused") private static class Holder { long field1 = 5000L; String name = "name"; Holder holder; long field2, field3, field4; Holder() {} Holder(String name, long field1) { this.name = name; this.field1 = field1; } } @SuppressWarnings("unused") private static class HolderSubclass extends Holder { byte foo; int bar; } private static class HolderSubclass2 extends Holder { // empty, only inherits all fields -> size should be identical to superclass } }