comparison test/gc/survivorAlignment/AlignmentHelper.java @ 20717:4b7c96fba3d8

8037968: Add tests on alignment of objects copied to survivor space Reviewed-by: jmasa, dfazunen
author fzhinkin
date Wed, 26 Nov 2014 14:17:06 +0400
parents
children
comparison
equal deleted inserted replaced
20716:7e70976b4d0f 20717:4b7c96fba3d8
1 /*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.lang.management.MemoryPoolMXBean;
25 import java.util.Optional;
26
27 import sun.hotspot.WhiteBox;
28
29 /**
30 * Helper class aimed to provide information about alignment of objects in
31 * particular heap space, expected memory usage after objects' allocation so on.
32 */
33 public class AlignmentHelper {
34 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
35
36 private static final long OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM = 8L;
37
38 /**
39 * Max relative allowed actual memory usage deviation from expected memory
40 * usage.
41 */
42 private static final float MAX_RELATIVE_DEVIATION = 0.05f; // 5%
43
44 public static final long OBJECT_ALIGNMENT_IN_BYTES = Optional.ofNullable(
45 AlignmentHelper.WHITE_BOX.getIntxVMFlag("ObjectAlignmentInBytes"))
46 .orElse(AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM);
47
48 public static final long SURVIVOR_ALIGNMENT_IN_BYTES = Optional.ofNullable(
49 AlignmentHelper.WHITE_BOX.getIntxVMFlag("SurvivorAlignmentInBytes"))
50 .orElseThrow(() ->new AssertionError(
51 "Unable to get SurvivorAlignmentInBytes value"));
52 /**
53 * Min amount of memory that will be occupied by an object.
54 */
55 public static final long MIN_OBJECT_SIZE
56 = AlignmentHelper.WHITE_BOX.getObjectSize(new Object());
57 /**
58 * Min amount of memory that will be occupied by an empty byte array.
59 */
60 public static final long MIN_ARRAY_SIZE
61 = AlignmentHelper.WHITE_BOX.getObjectSize(new byte[0]);
62
63 /**
64 * Precision at which actual memory usage in a heap space represented by
65 * this sizing helper could be measured.
66 */
67 private final long memoryUsageMeasurementPrecision;
68 /**
69 * Min amount of memory that will be occupied by an object allocated in a
70 * heap space represented by this sizing helper.
71 */
72 private final long minObjectSizeInThisSpace;
73 /**
74 * Object's alignment in a heap space represented by this sizing helper.
75 */
76 private final long objectAlignmentInThisRegion;
77 /**
78 * MemoryPoolMXBean associated with a heap space represented by this sizing
79 * helper.
80 */
81 private final MemoryPoolMXBean poolMXBean;
82
83 private static long alignUp(long value, long alignment) {
84 return ((value - 1) / alignment + 1) * alignment;
85 }
86
87 protected AlignmentHelper(long memoryUsageMeasurementPrecision,
88 long objectAlignmentInThisRegion, long minObjectSizeInThisSpace,
89 MemoryPoolMXBean poolMXBean) {
90 this.memoryUsageMeasurementPrecision = memoryUsageMeasurementPrecision;
91 this.minObjectSizeInThisSpace = minObjectSizeInThisSpace;
92 this.objectAlignmentInThisRegion = objectAlignmentInThisRegion;
93 this.poolMXBean = poolMXBean;
94 }
95
96 /**
97 * Returns how many objects have to be allocated to fill
98 * {@code memoryToFill} bytes in this heap space using objects of size
99 * {@code objectSize}.
100 */
101 public int getObjectsCount(long memoryToFill, long objectSize) {
102 return (int) (memoryToFill / getObjectSizeInThisSpace(objectSize));
103 }
104
105 /**
106 * Returns amount of memory that {@code objectsCount} of objects with size
107 * {@code objectSize} will occupy this this space after allocation.
108 */
109 public long getExpectedMemoryUsage(long objectSize, int objectsCount) {
110 long correctedObjectSize = getObjectSizeInThisSpace(objectSize);
111 return AlignmentHelper.alignUp(correctedObjectSize * objectsCount,
112 memoryUsageMeasurementPrecision);
113 }
114
115 /**
116 * Returns current memory usage in this heap space.
117 */
118 public long getActualMemoryUsage() {
119 return poolMXBean.getUsage().getUsed();
120 }
121
122 /**
123 * Returns maximum memory usage deviation from {@code expectedMemoryUsage}
124 * given the max allowed relative deviation equal to
125 * {@code relativeDeviation}.
126 *
127 * Note that value returned by this method is aligned according to
128 * memory measurement precision for this heap space.
129 */
130 public long getAllowedMemoryUsageDeviation(long expectedMemoryUsage) {
131 long unalignedDeviation = (long) (expectedMemoryUsage *
132 AlignmentHelper.MAX_RELATIVE_DEVIATION);
133 return AlignmentHelper.alignUp(unalignedDeviation,
134 memoryUsageMeasurementPrecision);
135 }
136
137 /**
138 * Returns amount of memory that will be occupied by an object with size
139 * {@code objectSize} in this heap space.
140 */
141 public long getObjectSizeInThisSpace(long objectSize) {
142 objectSize = Math.max(objectSize, minObjectSizeInThisSpace);
143
144 long alignedObjectSize = AlignmentHelper.alignUp(objectSize,
145 objectAlignmentInThisRegion);
146 long sizeDiff = alignedObjectSize - objectSize;
147
148 // If there is not enough space to fit padding object, then object will
149 // be aligned to {@code 2 * objectAlignmentInThisRegion}.
150 if (sizeDiff >= AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES
151 && sizeDiff < AlignmentHelper.MIN_OBJECT_SIZE) {
152 alignedObjectSize += AlignmentHelper.MIN_OBJECT_SIZE;
153 alignedObjectSize = AlignmentHelper.alignUp(alignedObjectSize,
154 objectAlignmentInThisRegion);
155 }
156
157 return alignedObjectSize;
158 }
159 @Override
160 public String toString() {
161 StringBuilder builder = new StringBuilder();
162
163 builder.append(String.format("AlignmentHelper for memory pool '%s':%n",
164 poolMXBean.getName()));
165 builder.append(String.format("Memory usage measurement precision: %d%n",
166 memoryUsageMeasurementPrecision));
167 builder.append(String.format("Min object size in this space: %d%n",
168 minObjectSizeInThisSpace));
169 builder.append(String.format("Object alignment in this space: %d%n",
170 objectAlignmentInThisRegion));
171
172 return builder.toString();
173 }
174 }