21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.nashorn.internal.ir.debug;
27
28 import java.lang.reflect.Array;
29 import java.lang.reflect.Field;
30 import java.lang.reflect.InvocationTargetException;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Modifier;
33 import java.util.ArrayDeque;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Deque;
37 import java.util.IdentityHashMap;
38 import java.util.LinkedList;
39 import java.util.List;
40 import java.util.Map;
41
42 /**
43 * Contains utility methods for calculating the memory usage of objects. It
44 * only works on the HotSpot JVM, and infers the actual memory layout (32 bit
45 * vs. 64 bit word size, compressed object pointers vs. uncompressed) from
46 * best available indicators. It can reliably detect a 32 bit vs. 64 bit JVM.
47 * It can only make an educated guess at whether compressed OOPs are used,
48 * though; specifically, it knows what the JVM's default choice of OOP
49 * compression would be based on HotSpot version and maximum heap sizes, but if
50 * the choice is explicitly overridden with the <tt>-XX:{+|-}UseCompressedOops</tt> command line
51 * switch, it can not detect
52 * this fact and will report incorrect sizes, as it will presume the default JVM
53 * behavior.
54 */
55 public final class ObjectSizeCalculator {
56
57 /**
58 * Describes constant memory overheads for various constructs in a JVM implementation.
59 */
60 public interface MemoryLayoutSpecification {
133 // Padding for the fields of superclass before fields of subclasses are
134 // added.
135 private final int superclassFieldPadding;
136
137 private final Map<Class<?>, ClassSizeInfo> classSizeInfos = new IdentityHashMap<>();
138
139
140 private final Map<Object, Object> alreadyVisited = new IdentityHashMap<>();
141 private final Map<Class<?>, ClassHistogramElement> histogram = new IdentityHashMap<>();
142
143 private final Deque<Object> pending = new ArrayDeque<>(16 * 1024);
144 private long size;
145
146 /**
147 * Creates an object size calculator that can calculate object sizes for a given
148 * {@code memoryLayoutSpecification}.
149 *
150 * @param memoryLayoutSpecification a description of the JVM memory layout.
151 */
152 public ObjectSizeCalculator(final MemoryLayoutSpecification memoryLayoutSpecification) {
153 memoryLayoutSpecification.getClass();
154 arrayHeaderSize = memoryLayoutSpecification.getArrayHeaderSize();
155 objectHeaderSize = memoryLayoutSpecification.getObjectHeaderSize();
156 objectPadding = memoryLayoutSpecification.getObjectPadding();
157 referenceSize = memoryLayoutSpecification.getReferenceSize();
158 superclassFieldPadding = memoryLayoutSpecification.getSuperclassFieldPadding();
159 }
160
161 /**
162 * Given an object, returns the total allocated size, in bytes, of the object
163 * and all other objects reachable from it.
164 *
165 * @param obj the object; can be null. Passing in a {@link java.lang.Class} object doesn't do
166 * anything special, it measures the size of all objects
167 * reachable through it (which will include its class loader, and by
168 * extension, all other Class objects loaded by
169 * the same loader, and all the parent class loaders). It doesn't provide the
170 * size of the static fields in the JVM class that the Class object
171 * represents.
172 * @return the total allocated size of the object and all other objects it
173 * retains.
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.nashorn.internal.ir.debug;
27
28 import java.lang.reflect.Array;
29 import java.lang.reflect.Field;
30 import java.lang.reflect.InvocationTargetException;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Modifier;
33 import java.util.ArrayDeque;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Deque;
37 import java.util.IdentityHashMap;
38 import java.util.LinkedList;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Objects;
42
43 /**
44 * Contains utility methods for calculating the memory usage of objects. It
45 * only works on the HotSpot JVM, and infers the actual memory layout (32 bit
46 * vs. 64 bit word size, compressed object pointers vs. uncompressed) from
47 * best available indicators. It can reliably detect a 32 bit vs. 64 bit JVM.
48 * It can only make an educated guess at whether compressed OOPs are used,
49 * though; specifically, it knows what the JVM's default choice of OOP
50 * compression would be based on HotSpot version and maximum heap sizes, but if
51 * the choice is explicitly overridden with the <tt>-XX:{+|-}UseCompressedOops</tt> command line
52 * switch, it can not detect
53 * this fact and will report incorrect sizes, as it will presume the default JVM
54 * behavior.
55 */
56 public final class ObjectSizeCalculator {
57
58 /**
59 * Describes constant memory overheads for various constructs in a JVM implementation.
60 */
61 public interface MemoryLayoutSpecification {
134 // Padding for the fields of superclass before fields of subclasses are
135 // added.
136 private final int superclassFieldPadding;
137
138 private final Map<Class<?>, ClassSizeInfo> classSizeInfos = new IdentityHashMap<>();
139
140
141 private final Map<Object, Object> alreadyVisited = new IdentityHashMap<>();
142 private final Map<Class<?>, ClassHistogramElement> histogram = new IdentityHashMap<>();
143
144 private final Deque<Object> pending = new ArrayDeque<>(16 * 1024);
145 private long size;
146
147 /**
148 * Creates an object size calculator that can calculate object sizes for a given
149 * {@code memoryLayoutSpecification}.
150 *
151 * @param memoryLayoutSpecification a description of the JVM memory layout.
152 */
153 public ObjectSizeCalculator(final MemoryLayoutSpecification memoryLayoutSpecification) {
154 Objects.requireNonNull(memoryLayoutSpecification);
155 arrayHeaderSize = memoryLayoutSpecification.getArrayHeaderSize();
156 objectHeaderSize = memoryLayoutSpecification.getObjectHeaderSize();
157 objectPadding = memoryLayoutSpecification.getObjectPadding();
158 referenceSize = memoryLayoutSpecification.getReferenceSize();
159 superclassFieldPadding = memoryLayoutSpecification.getSuperclassFieldPadding();
160 }
161
162 /**
163 * Given an object, returns the total allocated size, in bytes, of the object
164 * and all other objects reachable from it.
165 *
166 * @param obj the object; can be null. Passing in a {@link java.lang.Class} object doesn't do
167 * anything special, it measures the size of all objects
168 * reachable through it (which will include its class loader, and by
169 * extension, all other Class objects loaded by
170 * the same loader, and all the parent class loaders). It doesn't provide the
171 * size of the static fields in the JVM class that the Class object
172 * represents.
173 * @return the total allocated size of the object and all other objects it
174 * retains.
|