Why is there internal fragmentation in a Java object even if every field is 4-byte aligned?

后端 未结 2 1984
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-02 17:50

Intro:

I used the JOL (Java Object Layout) tool to analyze the internal and external fragmentation of Java objects for research purpose.

Whi

相关标签:
2条回答
  • 2021-01-02 18:11

    Sometimes HotSpot injects internal VM-specific fields that are not visible on Java level. In ClassLoader case this is a pointer to ClassLoaderData:

    #define CLASSLOADER_INJECTED_FIELDS(macro)                            \
      macro(java_lang_ClassLoader, loader_data,  intptr_signature, false)
    

    This is one field of intptr_t type, i.e. exactly 8 bytes long.

    Here is how HotSpot sources describe ClassLoaderData:

    // A ClassLoaderData identifies the full set of class types that a class
    // loader's name resolution strategy produces for a given configuration of the
    // class loader.
    // Class types in the ClassLoaderData may be defined by from class file binaries
    // provided by the class loader, or from other class loader it interacts with
    // according to its name resolution strategy.
    //
    // Class loaders that implement a deterministic name resolution strategy
    // (including with respect to their delegation behavior), such as the boot, the
    // extension, and the system loaders of the JDK's built-in class loader
    // hierarchy, always produce the same linkset for a given configuration.
    //
    // ClassLoaderData carries information related to a linkset (e.g.,
    // metaspace holding its klass definitions).
    // The System Dictionary and related data structures (e.g., placeholder table,
    // loader constraints table) as well as the runtime representation of classes
    // only reference ClassLoaderData.
    //
    // Instances of java.lang.ClassLoader holds a pointer to a ClassLoaderData that
    // that represent the loader's "linking domain" in the JVM.
    //
    // The bootstrap loader (represented by NULL) also has a ClassLoaderData,
    // the singleton class the_null_class_loader_data().
    
    0 讨论(0)
  • 2021-01-02 18:27

    You have given me a perfect opportunity to post something that I have seen interesting too (this should be a comment, but it's too long):

      System.out.println(ClassLayout.parseInstance(Class.class).toPrintable());
    

    Running this will give you:

     OFFSET  SIZE            TYPE DESCRIPTION                    VALUE
      0     4                 (object header)                01 27 2b fd (00000001 00100111 00101011 11111101) (-47503615)
      4     4                 (object header)                5f 00 00 00 (01011111 00000000 00000000 00000000) (95)
      8     4                 (object header)                df 03 00 f8 (11011111 00000011 00000000 11111000) (-134216737)
     12     4     Constructor Class.cachedConstructor        null
     16     4           Class Class.newInstanceCallerCache   null
     20     4          String Class.name                     (object)
     24     4                 (alignment/padding gap)        N/A
     28     4   SoftReference Class.reflectionData           (object)
     32     4 ClassRepository Class.genericInfo              null
     36     4        Object[] Class.enumConstants            null
     40     4             Map Class.enumConstantDirectory    null
     44     4  AnnotationData Class.annotationData           (object)
     48     4  AnnotationType Class.annotationType           null
     52     4   ClassValueMap Class.classValueMap            null
     56    32                 (alignment/padding gap)        N/A
     88     4             int Class.classRedefinedCount      0
     92   556                 (loss due to the next object alignment)
    

    Instance size: 648 bytes Space losses: 36 bytes internal + 556 bytes external = 592 bytes total

    Or a total space loss of 556 bytes; I found this pretty impressive.

    0 讨论(0)
提交回复
热议问题