Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/test/gc/survivorAlignment/AlignmentHelper.java
32284 views
/*1* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.lang.management.MemoryPoolMXBean;24import java.util.Optional;2526import sun.hotspot.WhiteBox;2728/**29* Helper class aimed to provide information about alignment of objects in30* particular heap space, expected memory usage after objects' allocation so on.31*/32public class AlignmentHelper {33private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();3435private static final long OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM = 8L;3637/**38* Max relative allowed actual memory usage deviation from expected memory39* usage.40*/41private static final float MAX_RELATIVE_DEVIATION = 0.05f; // 5%4243public static final long OBJECT_ALIGNMENT_IN_BYTES = Optional.ofNullable(44AlignmentHelper.WHITE_BOX.getIntxVMFlag("ObjectAlignmentInBytes"))45.orElse(AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM);4647public static final long SURVIVOR_ALIGNMENT_IN_BYTES = Optional.ofNullable(48AlignmentHelper.WHITE_BOX.getIntxVMFlag("SurvivorAlignmentInBytes"))49.orElseThrow(() ->new AssertionError(50"Unable to get SurvivorAlignmentInBytes value"));51/**52* Min amount of memory that will be occupied by an object.53*/54public static final long MIN_OBJECT_SIZE55= AlignmentHelper.WHITE_BOX.getObjectSize(new Object());56/**57* Min amount of memory that will be occupied by an empty byte array.58*/59public static final long MIN_ARRAY_SIZE60= AlignmentHelper.WHITE_BOX.getObjectSize(new byte[0]);6162/**63* Precision at which actual memory usage in a heap space represented by64* this sizing helper could be measured.65*/66private final long memoryUsageMeasurementPrecision;67/**68* Min amount of memory that will be occupied by an object allocated in a69* heap space represented by this sizing helper.70*/71private final long minObjectSizeInThisSpace;72/**73* Object's alignment in a heap space represented by this sizing helper.74*/75private final long objectAlignmentInThisRegion;76/**77* MemoryPoolMXBean associated with a heap space represented by this sizing78* helper.79*/80private final MemoryPoolMXBean poolMXBean;8182private static long alignUp(long value, long alignment) {83return ((value - 1) / alignment + 1) * alignment;84}8586protected AlignmentHelper(long memoryUsageMeasurementPrecision,87long objectAlignmentInThisRegion, long minObjectSizeInThisSpace,88MemoryPoolMXBean poolMXBean) {89this.memoryUsageMeasurementPrecision = memoryUsageMeasurementPrecision;90this.minObjectSizeInThisSpace = minObjectSizeInThisSpace;91this.objectAlignmentInThisRegion = objectAlignmentInThisRegion;92this.poolMXBean = poolMXBean;93}9495/**96* Returns how many objects have to be allocated to fill97* {@code memoryToFill} bytes in this heap space using objects of size98* {@code objectSize}.99*/100public int getObjectsCount(long memoryToFill, long objectSize) {101return (int) (memoryToFill / getObjectSizeInThisSpace(objectSize));102}103104/**105* Returns amount of memory that {@code objectsCount} of objects with size106* {@code objectSize} will occupy this this space after allocation.107*/108public long getExpectedMemoryUsage(long objectSize, int objectsCount) {109long correctedObjectSize = getObjectSizeInThisSpace(objectSize);110return AlignmentHelper.alignUp(correctedObjectSize * objectsCount,111memoryUsageMeasurementPrecision);112}113114/**115* Returns current memory usage in this heap space.116*/117public long getActualMemoryUsage() {118return poolMXBean.getUsage().getUsed();119}120121/**122* Returns maximum memory usage deviation from {@code expectedMemoryUsage}123* given the max allowed relative deviation equal to124* {@code relativeDeviation}.125*126* Note that value returned by this method is aligned according to127* memory measurement precision for this heap space.128*/129public long getAllowedMemoryUsageDeviation(long expectedMemoryUsage) {130long unalignedDeviation = (long) (expectedMemoryUsage *131AlignmentHelper.MAX_RELATIVE_DEVIATION);132return AlignmentHelper.alignUp(unalignedDeviation,133memoryUsageMeasurementPrecision);134}135136/**137* Returns amount of memory that will be occupied by an object with size138* {@code objectSize} in this heap space.139*/140public long getObjectSizeInThisSpace(long objectSize) {141objectSize = Math.max(objectSize, minObjectSizeInThisSpace);142143long alignedObjectSize = AlignmentHelper.alignUp(objectSize,144objectAlignmentInThisRegion);145long sizeDiff = alignedObjectSize - objectSize;146147// If there is not enough space to fit padding object, then object will148// be aligned to {@code 2 * objectAlignmentInThisRegion}.149if (sizeDiff >= AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES150&& sizeDiff < AlignmentHelper.MIN_OBJECT_SIZE) {151alignedObjectSize += AlignmentHelper.MIN_OBJECT_SIZE;152alignedObjectSize = AlignmentHelper.alignUp(alignedObjectSize,153objectAlignmentInThisRegion);154}155156return alignedObjectSize;157}158@Override159public String toString() {160StringBuilder builder = new StringBuilder();161162builder.append(String.format("AlignmentHelper for memory pool '%s':%n",163poolMXBean.getName()));164builder.append(String.format("Memory usage measurement precision: %d%n",165memoryUsageMeasurementPrecision));166builder.append(String.format("Min object size in this space: %d%n",167minObjectSizeInThisSpace));168builder.append(String.format("Object alignment in this space: %d%n",169objectAlignmentInThisRegion));170171return builder.toString();172}173}174175176