java.lang.instrument.Instrumentation.getObjectSize for java.lang.Class instance
David Holmes
david.holmes at oracle.com
Sun Dec 16 18:01:18 PST 2012
On 15/12/2012 4:40 AM, Krystal Mok wrote:
> Hi Peter,
>
> Which version of JDK are you using? Assuming you're using a JDK6/JDK7
> version released to date, the actual implementation for
> j.l.i.Instrumentation.getObjectSize() is as follows:
>
> jvmtiError
> JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {
> oop mirror = JNIHandles::resolve_external_guard(object);
> NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
>
> if (mirror->klass() == SystemDictionary::Class_klass()) {
> if (!java_lang_Class::is_primitive(mirror)) {
> mirror = java_lang_Class::as_klassOop(mirror);
> assert(mirror != NULL, "class for non-primitive mirror must exist");
> }
> }
>
> *size_ptr = mirror->size() * wordSize;
> return JVMTI_ERROR_NONE;
> } /* end GetObjectSize */
>
> So there's special handling for j.l.Class instances' size: it's
> reporting the size of the klassOop (the VM internal type that holds
> the metadata). That's why changing the number of fields in j.l.Class
> doesn't affect the result of getObjectSize(clazz).
I had slightly different variants in the testing code I previously put
together for JEP-149 - see below.
But the key thing is that you need two different API's here: one for
regular objects and one for Class instances. To that end
Instrumentation.getObjectSize is not that useful for Class instances,
but I think the implementation chosen is not what people would generally
want when asking about Class sizes.
David
+// Return the size of an instance of cls
+JVM_ENTRY(jlong, JVM_Sizeof(JNIEnv *env, jclass ignored, jclass cls))
+ JVMWrapper("JVM_Sizeof");
+ // Check if we have null pointers
+ if (cls == NULL) {
+ THROW_0(vmSymbols::java_lang_NullPointerException());
+ }
+ oop mirror = JNIHandles::resolve_non_null(cls);
+
+ // exclude primitives and arrays
+ if (java_lang_Class::is_primitive(mirror) /*|| is array */) {
+ THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+ }
+ klassOop klass = java_lang_Class::as_klassOop(mirror);
+ return align_object_size(instanceKlass::cast(klass)->size_helper())
<< LogHeapWordSize;
+JVM_END
+
+// Return the size of cls - which is the base size for any instance
+// of java.lang.Class plus any static fields for this particular Class
+JVM_ENTRY(jlong, JVM_SizeofClass(JNIEnv *env, jclass ignored, jclass cls))
+ JVMWrapper("JVM_SizeofClass");
+ // Check if we have null pointers
+ if (cls == NULL) {
+ THROW_0(vmSymbols::java_lang_NullPointerException());
+ }
+ oop mirror = JNIHandles::resolve_non_null(cls);
+ return mirror->size() << LogHeapWordSize;
+JVM_END
More information about the hotspot-runtime-dev
mailing list