Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7185456

(ann) Optimize Annotation handling in java/sun.reflect.* code for small number of annotationsC



    • b86
    • generic
    • generic
    • Verified



        Analysis of heap dumps by the JOverflow tool suggests that in business applications, in particular Oracle Fusion Apps, there may be up to 100,000..150,000 instances of the following classes. See this excerpt from JOverflow report for a heap dump for CRMDomain-MarketingServer application:

        Object histogram for top memory consumers
         #instances Shallow size Impl-inclusive size Class name
            84,223 11,843K (1.0%) 11,843K (1.0%) java.lang.reflect.Method
            31,900 3,738K (0.3%) 3,738K (0.3%) java.lang.reflect.Field
            29,987 3,279K (0.3%) 3,279K (0.3%) java.lang.reflect.Constructor
            47,526 1,485K (0.1%) 1,485K (0.1%) sun.reflect.annotation.AnnotationInvocationHandler

        These classes store information about annotations for the corresponding members in LinkedHashMaps. There are typically just a few annotations for a given member. However, for a LinkedHashMap the default size of the 'buckets' array is 16, and it looks like these maps are allocated with the default size in the relevant JDK code. As a result, a noticeable amount of memory gets wasted due to the null pointers in 'bucket' arrays of LinkedHashMaps. Here is what JOverflow reports:

          sun.reflect.annotation.AnnotationInvocationHandler.memberValues -->
        10,438K (0.9%): LinkedHashMap: 31207 of SMALL 7,615K (0.6%), 46052 of SPARSE_SMALL 2,342K (0.2%), 1084 of BOXED 255K (0.0%), 1440 of EMPTY 225K (0.0%)

          java.lang.reflect.Field.declaredAnnotations -->
        4,300K (0.4%): LinkedHashMap: 17380 of SMALL 3,296K (0.3%), 17380 of SPARSE_SMALL 1,003K (0.1%)

          java.lang.reflect.Method.declaredAnnotations -->
        2,031K (0.2%): LinkedHashMap: 6791 of SMALL 1,605K (0.1%), 8191 of SPARSE_SMALL 426K (0.0%)

        The amount of memory being wasted under SPARSE_SMALL category (which means that less than half of the default 16 slots are used in the map) can be very easily reduced if the respective LinkedHashMaps are allocated with non-default initial size of say 4.

        Even more memory (see the SMALL category, which means that the respective map contains 4 elements or fewer) can be saved if LinkedHashMaps are replaced with small ArrayLists or just arrays. Since in most cases the number of annotations is small, simple sequential lookup in lists will likely result in no noticeable performance difference compared to hash map lookup.


          Issue Links



                darcy Joe Darcy
                mdmitrie Misha Dmitriev (Inactive)
                0 Vote for this issue
                4 Start watching this issue