Every time we encounter a new Entity (the document itself is treated as an entity), XMLEntityManager.startEntity method is called. This method in turn creates new instances of RewindableInputStream, Entity.ScannedEntity and a ???Reader (???=UTF8/ASCII/UCS etc.).
The RewindableInputStream wraps the InputStream in a buffer that can be rewound and re-read. The RewindableInputStream allocates a byte array of size DEFAULT_XMLDECL_BUFFER_SIZE = 64. ScannedEntity creates a new char array of either 8192 or 1024 bytes depending upon whether the entity is external or internal, respectively. The Reader (UTF8Reader is what I experimented with) creates a byte array, typically of same size as the ScannedEntity's char array (8192 for the document entity). Thus for every Entity, we allocate three buffers which can turn out to be relatively expensive operations, especially, if the documents are pretty small. One way to avoid these allocations are to use a buffer pool to allocate these buffers and return them when the parsing of entities are completed. The key issue is identifying when to release the buffers.
Preliminary performance results indicate that 2-3X better performance is achievable on small messages (< 1KB) by implementing a better buffer allocation strategy.