Mercurial > hg > truffle
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 } |