patrickmhaller opened a new issue, #992:
URL: https://github.com/apache/poi/issues/992

   Dear POI/XMLBeans team,
   
   I need to fill data into an externally provided Excel sheet that unfolds to 
600MB JVM heap after parsing into an XSSFWorkbook.
   Analysis via [JOL](https://github.com/openjdk/jol) shows
   - 2.35 mio org.apache.xmlbeans.impl.store.AttrXobj, worth 216MB
   - 1.17 mio org.apache.xmlbeans.impl.store.ElementXobj, worth 108MB
   
   In attempt to reduce the memory footprint, I propose below non-invasive 
change that can provide ~3% reduction in memory footprint, depending on the 
processed Excel file.
   
   By turning `int _bits` into `short _bits`, the JVM can better pack `Xobj`and 
subclasses.
   `Xobj` and `ElementXobj` do not change in size due to object alignment gaps.
   However `AttrXobj` shrinks **from 96 bytes** (with a 7 byte object alignment 
gap) **to 88 bytes** (with 1 byte gap).
   
   All 2965 xmlbeans tests succeeded locally, performance looked identical, and 
none of the assertions triggered.
   The proposed patch looks good to me and I'd hope for merging into the next 
release.
   
   
   ## XMLBeans master (unoptimized)
   ```
   ---[ class org.apache.xmlbeans.impl.store.Xobj 
]-------------------------------------
   org.apache.xmlbeans.impl.store.Xobj object internals:
   OFF  SZ                                            TYPE DESCRIPTION          
     VALUE
     0   8                                                 (object header: 
mark)     N/A
     8   4                                                 (object header: 
class)    N/A
    12   4                                             int Xobj._bits           
     N/A
    16   4                                             int Xobj._offValue       
     N/A
    20   4                                             int Xobj._offAfter       
     N/A
    24   4                                             int Xobj._cchValue       
     N/A
    28   4                                             int Xobj._cchAfter       
     N/A
    32   4           org.apache.xmlbeans.impl.store.Locale Xobj._locale         
     N/A
    36   4                       javax.xml.namespace.QName Xobj._name           
     N/A
    40   4              org.apache.xmlbeans.impl.store.Cur Xobj._embedded       
     N/A
    44   4         org.apache.xmlbeans.impl.store.Bookmark Xobj._bookmarks      
     N/A
    48   4             org.apache.xmlbeans.impl.store.Xobj Xobj._parent         
     N/A
    52   4             org.apache.xmlbeans.impl.store.Xobj Xobj._nextSibling    
     N/A
    56   4             org.apache.xmlbeans.impl.store.Xobj Xobj._prevSibling    
     N/A
    60   4             org.apache.xmlbeans.impl.store.Xobj Xobj._firstChild     
     N/A
    64   4             org.apache.xmlbeans.impl.store.Xobj Xobj._lastChild      
     N/A
    68   4                                java.lang.Object Xobj._srcValue       
     N/A
    72   4                                java.lang.Object Xobj._srcAfter       
     N/A
    76   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesValue 
     N/A
    80   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesAfter 
     N/A
    84   4   org.apache.xmlbeans.impl.values.TypeStoreUser Xobj._user           
     N/A
   Instance size: 88 bytes
   Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
   
   ---[ class org.apache.xmlbeans.impl.store.AttrXobj 
]-------------------------------------
   org.apache.xmlbeans.impl.store.AttrXobj object internals:
   OFF  SZ                                            TYPE DESCRIPTION          
             VALUE
     0   8                                                 (object header: 
mark)             N/A
     8   4                                                 (object header: 
class)            N/A
    12   4                                             int Xobj._bits           
             N/A
    16   4                                             int Xobj._offValue       
             N/A
    20   4                                             int Xobj._offAfter       
             N/A
    24   4                                             int Xobj._cchValue       
             N/A
    28   4                                             int Xobj._cchAfter       
             N/A
    32   4           org.apache.xmlbeans.impl.store.Locale Xobj._locale         
             N/A
    36   4                       javax.xml.namespace.QName Xobj._name           
             N/A
    40   4              org.apache.xmlbeans.impl.store.Cur Xobj._embedded       
             N/A
    44   4         org.apache.xmlbeans.impl.store.Bookmark Xobj._bookmarks      
             N/A
    48   4             org.apache.xmlbeans.impl.store.Xobj Xobj._parent         
             N/A
    52   4             org.apache.xmlbeans.impl.store.Xobj Xobj._nextSibling    
             N/A
    56   4             org.apache.xmlbeans.impl.store.Xobj Xobj._prevSibling    
             N/A
    60   4             org.apache.xmlbeans.impl.store.Xobj Xobj._firstChild     
             N/A
    64   4             org.apache.xmlbeans.impl.store.Xobj Xobj._lastChild      
             N/A
    68   4                                java.lang.Object Xobj._srcValue       
             N/A
    72   4                                java.lang.Object Xobj._srcAfter       
             N/A
    76   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesValue 
             N/A
    80   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesAfter 
             N/A
    84   4   org.apache.xmlbeans.impl.values.TypeStoreUser Xobj._user           
             N/A
    88   1                                         boolean 
NamedNodeXobj._canHavePrefixUri   N/A
    89   7                                                 (object alignment 
gap)            
   Instance size: 96 bytes
   Space losses: 0 bytes internal + 7 bytes external = 7 bytes total
   
   ---[ class org.apache.xmlbeans.impl.store.ElementXobj 
]-------------------------------------
   org.apache.xmlbeans.impl.store.ElementXobj object internals:
   OFF  SZ                                               TYPE DESCRIPTION       
                VALUE
     0   8                                                    (object header: 
mark)             N/A
     8   4                                                    (object header: 
class)            N/A
    12   4                                                int Xobj._bits        
                N/A
    16   4                                                int Xobj._offValue    
                N/A
    20   4                                                int Xobj._offAfter    
                N/A
    24   4                                                int Xobj._cchValue    
                N/A
    28   4                                                int Xobj._cchAfter    
                N/A
    32   4              org.apache.xmlbeans.impl.store.Locale Xobj._locale      
                N/A
    36   4                          javax.xml.namespace.QName Xobj._name        
                N/A
    40   4                 org.apache.xmlbeans.impl.store.Cur Xobj._embedded    
                N/A
    44   4            org.apache.xmlbeans.impl.store.Bookmark Xobj._bookmarks   
                N/A
    48   4                org.apache.xmlbeans.impl.store.Xobj Xobj._parent      
                N/A
    52   4                org.apache.xmlbeans.impl.store.Xobj Xobj._nextSibling 
                N/A
    56   4                org.apache.xmlbeans.impl.store.Xobj Xobj._prevSibling 
                N/A
    60   4                org.apache.xmlbeans.impl.store.Xobj Xobj._firstChild  
                N/A
    64   4                org.apache.xmlbeans.impl.store.Xobj Xobj._lastChild   
                N/A
    68   4                                   java.lang.Object Xobj._srcValue    
                N/A
    72   4                                   java.lang.Object Xobj._srcAfter    
                N/A
    76   4            org.apache.xmlbeans.impl.store.CharNode 
Xobj._charNodesValue              N/A
    80   4            org.apache.xmlbeans.impl.store.CharNode 
Xobj._charNodesAfter              N/A
    84   4      org.apache.xmlbeans.impl.values.TypeStoreUser Xobj._user        
                N/A
    88   1                                            boolean 
NamedNodeXobj._canHavePrefixUri   N/A
    89   3                                                    
(alignment/padding gap)           
    92   4   org.apache.xmlbeans.impl.store.ElementAttributes 
ElementXobj._attributes           N/A
   Instance size: 96 bytes
   Space losses: 3 bytes internal + 0 bytes external = 3 bytes total
   ```
   
   ## Micro-optimized with "short _bits"
   ```
   ---[ class org.apache.xmlbeans.impl.store.Xobj 
]-------------------------------------
   org.apache.xmlbeans.impl.store.Xobj object internals:
   OFF  SZ                                            TYPE DESCRIPTION          
     VALUE
     0   8                                                 (object header: 
mark)     N/A
     8   4                                                 (object header: 
class)    N/A
    12   4                                             int Xobj._offValue       
     N/A
    16   4                                             int Xobj._offAfter       
     N/A
    20   4                                             int Xobj._cchValue       
     N/A
    24   4                                             int Xobj._cchAfter       
     N/A
    28   2                                           short Xobj._bits           
     N/A
    30   2                                                 (alignment/padding 
gap)   
    32   4           org.apache.xmlbeans.impl.store.Locale Xobj._locale         
     N/A
    36   4                       javax.xml.namespace.QName Xobj._name           
     N/A
    40   4              org.apache.xmlbeans.impl.store.Cur Xobj._embedded       
     N/A
    44   4         org.apache.xmlbeans.impl.store.Bookmark Xobj._bookmarks      
     N/A
    48   4             org.apache.xmlbeans.impl.store.Xobj Xobj._parent         
     N/A
    52   4             org.apache.xmlbeans.impl.store.Xobj Xobj._nextSibling    
     N/A
    56   4             org.apache.xmlbeans.impl.store.Xobj Xobj._prevSibling    
     N/A
    60   4             org.apache.xmlbeans.impl.store.Xobj Xobj._firstChild     
     N/A
    64   4             org.apache.xmlbeans.impl.store.Xobj Xobj._lastChild      
     N/A
    68   4                                java.lang.Object Xobj._srcValue       
     N/A
    72   4                                java.lang.Object Xobj._srcAfter       
     N/A
    76   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesValue 
     N/A
    80   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesAfter 
     N/A
    84   4   org.apache.xmlbeans.impl.values.TypeStoreUser Xobj._user           
     N/A
   Instance size: 88 bytes
   Space losses: 2 bytes internal + 0 bytes external = 2 bytes total
   
   ---[ class org.apache.xmlbeans.impl.store.AttrXobj 
]-------------------------------------
   org.apache.xmlbeans.impl.store.AttrXobj object internals:
   OFF  SZ                                            TYPE DESCRIPTION          
             VALUE
     0   8                                                 (object header: 
mark)             N/A
     8   4                                                 (object header: 
class)            N/A
    12   4                                             int Xobj._offValue       
             N/A
    16   4                                             int Xobj._offAfter       
             N/A
    20   4                                             int Xobj._cchValue       
             N/A
    24   4                                             int Xobj._cchAfter       
             N/A
    28   2                                           short Xobj._bits           
             N/A
    30   1                                         boolean 
NamedNodeXobj._canHavePrefixUri   N/A
    31   1                                                 (alignment/padding 
gap)           
    32   4           org.apache.xmlbeans.impl.store.Locale Xobj._locale         
             N/A
    36   4                       javax.xml.namespace.QName Xobj._name           
             N/A
    40   4              org.apache.xmlbeans.impl.store.Cur Xobj._embedded       
             N/A
    44   4         org.apache.xmlbeans.impl.store.Bookmark Xobj._bookmarks      
             N/A
    48   4             org.apache.xmlbeans.impl.store.Xobj Xobj._parent         
             N/A
    52   4             org.apache.xmlbeans.impl.store.Xobj Xobj._nextSibling    
             N/A
    56   4             org.apache.xmlbeans.impl.store.Xobj Xobj._prevSibling    
             N/A
    60   4             org.apache.xmlbeans.impl.store.Xobj Xobj._firstChild     
             N/A
    64   4             org.apache.xmlbeans.impl.store.Xobj Xobj._lastChild      
             N/A
    68   4                                java.lang.Object Xobj._srcValue       
             N/A
    72   4                                java.lang.Object Xobj._srcAfter       
             N/A
    76   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesValue 
             N/A
    80   4         org.apache.xmlbeans.impl.store.CharNode Xobj._charNodesAfter 
             N/A
    84   4   org.apache.xmlbeans.impl.values.TypeStoreUser Xobj._user           
             N/A
   Instance size: 88 bytes
   Space losses: 1 bytes internal + 0 bytes external = 1 bytes total
   
   ---[ class org.apache.xmlbeans.impl.store.ElementXobj 
]-------------------------------------
   org.apache.xmlbeans.impl.store.ElementXobj object internals:
   OFF  SZ                                               TYPE DESCRIPTION       
                VALUE
     0   8                                                    (object header: 
mark)             N/A
     8   4                                                    (object header: 
class)            N/A
    12   4                                                int Xobj._offValue    
                N/A
    16   4                                                int Xobj._offAfter    
                N/A
    20   4                                                int Xobj._cchValue    
                N/A
    24   4                                                int Xobj._cchAfter    
                N/A
    28   2                                              short Xobj._bits        
                N/A
    30   1                                            boolean 
NamedNodeXobj._canHavePrefixUri   N/A
    31   1                                                    
(alignment/padding gap)           
    32   4              org.apache.xmlbeans.impl.store.Locale Xobj._locale      
                N/A
    36   4                          javax.xml.namespace.QName Xobj._name        
                N/A
    40   4                 org.apache.xmlbeans.impl.store.Cur Xobj._embedded    
                N/A
    44   4            org.apache.xmlbeans.impl.store.Bookmark Xobj._bookmarks   
                N/A
    48   4                org.apache.xmlbeans.impl.store.Xobj Xobj._parent      
                N/A
    52   4                org.apache.xmlbeans.impl.store.Xobj Xobj._nextSibling 
                N/A
    56   4                org.apache.xmlbeans.impl.store.Xobj Xobj._prevSibling 
                N/A
    60   4                org.apache.xmlbeans.impl.store.Xobj Xobj._firstChild  
                N/A
    64   4                org.apache.xmlbeans.impl.store.Xobj Xobj._lastChild   
                N/A
    68   4                                   java.lang.Object Xobj._srcValue    
                N/A
    72   4                                   java.lang.Object Xobj._srcAfter    
                N/A
    76   4            org.apache.xmlbeans.impl.store.CharNode 
Xobj._charNodesValue              N/A
    80   4            org.apache.xmlbeans.impl.store.CharNode 
Xobj._charNodesAfter              N/A
    84   4      org.apache.xmlbeans.impl.values.TypeStoreUser Xobj._user        
                N/A
    88   4   org.apache.xmlbeans.impl.store.ElementAttributes 
ElementXobj._attributes           N/A
    92   4                                                    (object alignment 
gap)            
   Instance size: 96 bytes
   Space losses: 1 bytes internal + 4 bytes external = 5 bytes total
   ```
   
   
   ## Diff / Patch
   
   ```
   diff --git a/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java 
b/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java
   index 55391fe7..ce078228 100644
   --- a/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java
   +++ b/src/main/java/org/apache/xmlbeans/impl/store/Xobj.java
   @@ -41,9 +41,11 @@ abstract class Xobj implements TypeStore {
    
        Xobj(Locale l, int kind, int domType) {
            assert kind == ROOT || kind == ELEM || kind == ATTR || kind == 
COMMENT || kind == PROCINST;
   +        assert (kind & 0xFFFFFFF0) == 0 : "kind exceeds reserved bits in 
'short' range:" + kind;
   +        assert (domType & 0xFFFFFFF0) == 0 : "domType exceeds reserved bits 
in 'short' range:" + domType;
    
            _locale = l;
   -        _bits = (domType << 4) + kind;
   +        _bits = (short)((domType << 4) + kind);
        }
    
        final int kind() {
   @@ -1280,18 +1282,26 @@ abstract class Xobj implements TypeStore {
        //
    
        final void setBit(int mask) {
   +        assert (mask & 0xFFFF0000) == 0 : "mask exceeds 'short' range:" + 
mask;
   +
            _bits |= mask;
        }
    
        final void clearBit(int mask) {
   +        assert (mask & 0xFFFF0000) == 0 : "mask exceeds 'short' range:" + 
mask;
   +
            _bits &= ~mask;
        }
    
        final boolean bitIsSet(int mask) {
   +        assert (mask & 0xFFFF0000) == 0 : "mask exceeds 'short' range:" + 
mask;
   +
            return (_bits & mask) != 0;
        }
    
        final boolean bitIsClear(int mask) {
   +        assert (mask & 0xFFFF0000) == 0 : "mask exceeds 'short' range:" + 
mask;
   +
            return (_bits & mask) == 0;
        }
    
   @@ -2416,7 +2426,14 @@ abstract class Xobj implements TypeStore {
    
        Bookmark _bookmarks;
    
   -    int _bits;
   +    /* Memory-optimized bit field allows JVM to pack Xobj and subclasses 
more densely,
   +     * e. g. AttrXobj.
   +     *  0.. 3: kind
   +     *  4.. 7: domType
   +     *  8..11: VACANT, STABLE_USER, INHIBIT_DISCONNECT
   +     * 12..15: free for internal use
   +     */
   +    private short _bits;
    
        Xobj _parent;
        Xobj _nextSibling;
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to