Hints and Tips for Analyzing Java Heap Dumps
Tools
- Eclipse Memory Analyzer Tool (MAT) (free): https://www.eclipse.org/mat/
- VisualVM (free): https://visualvm.github.io
- YourKit Java Profiler (commercial): https://www.yourkit.com
Other tools are available, but these are commonly used for heap dump analysis.
Analysis Approaches
- Examine threads:
Review thread information to understand application state. Many tools display the thread where an OutOfMemoryError (OOM) occurred. This thread may indicate the root cause, but sometimes it is only the final trigger. In Tomcat environments, threads namedcatalina-exec-xyzcan often be correlated with specific HTTP requests. - Inspect large objects:
Use features such as Dominator Trees, Top Consumers, or Leak Suspects to identify the largest objects in memory.
Common Object Types
PersistenceManager / Bundle Cache
For example, org.apache.jackrabbit.core.persistence.pool.MySqlPersistenceManager represents the repository bundle cache. Typical sizes can reach up to 200MB, depending on data volume and configuration (such as bundle cache size).
HippoLocalItemStateManager
Instances of org.hippoecm.repository.jackrabbit.HippoLocalItemStateManager correspond to JCR sessions. Sizes up to 20MB are common. A normal system should have a few dozen of these objects at most.
HstManager
org.hippoecm.hst.configuration.model.HstManagerImpl holds the HST model. These objects can be several tens of megabytes, depending on the configuration. Usually, there are one or two instances (for live and preview).
HstRequestContext
org.hippoecm.hst.site.request.HstRequestContextImpl represents a single HST request, typically originating from a browser. These objects are often associated with a catalina-exec thread. Key properties are available in the baseURL field, for example:
requestContext.baseURL.hostName="www.mydomain.com"
requestContext.baseURL.requestPath="/mypath"
requestContext.baseURL.parameterMap.table.map.table.key=myparameter
requestContext.baseURL.parameterMap.table.map.table.value=myparametervalue
org.hippoecm.frontend.Main
If this class is present, the CMS is deployed. If absent, only the site or delivery tier is running.
Matching Large Objects to HTTP Requests
-
Correlate a large object with an HTTP request:
Use the "Path to GC roots" feature (or similar) in your analysis tool. This function traces references from the object to the root. If the root is acatalina-exec-xyzthread, the object is likely part of an incoming Tomcat request. -
Associate HST request context with the HTTP request:
Locate aHstRequestContextImplobject that references the samecatalina-exec-xyzthread. Inspect its properties (especiallybaseURL) to determine the request details. If your tool supports Object Query Language (OQL), use it to search forRequestContextImplobjects (see below).
Using Object Query Language (OQL)
If your analysis tool supports OQL, you can query for specific objects. For more information, see https://en.wikipedia.org/wiki/Object_Query_Language.
Example OQL queries:
select * from org.hippoecm.hst.site.request.HstRequestContextImpl
select * from org.hippoecm.hst.core.component.HstRequestImpl
select * from org.hippoecm.hst.configuration.model.HstManagerImpl
select toString(info.workerThreadName), toString(info.req.queryMB.byteC.buff) from org.apache.coyote.RequestInfo info
Common Out-of-Memory (OOM) Scenarios
Exploding Query
If a thread contains many org.apache.lucene.search.* objects (such as BooleanQuery, BooleanScorer2, TermScorer), an inefficient or overly broad query may be consuming excessive memory.
- To analyze, identify the URL from the
HstRequestContextand map it to the relevant page and components. - If the request is an HST query, you may also find the underlying JCR XPath queries in the thread.
- Exploding queries can result from misconfigured Faceted Navigation (for example, missing limits or inefficient queries).
Custom Cache with Node References
Custom cache implementations that store JCR node or property references can cause OOM errors, as these objects are not eligible for garbage collection.
- Do not store JCR node or property references in caches.
Excessive JCR Sessions
A large number of HippoLocalItemStateManager objects may indicate that the JCR session pool is exhausted.
Groovy Script with Large JCR Session
Custom Groovy scripts that attempt to save a large number of changes in a single operation can consume significant memory.
- In thread views, look for
org.onehippo.repository.update.UpdaterExecutorand large bundle cache objects.
URL Rewriter with Infinite Redirects
Misconfigured URL rewriters (for example, redirect loops) can fill memory with large String objects containing repeated URLs such as /https:/www.mydomain.nl/https:/www.mydomain.nl/....
Large YAML (XML) Download from Console
Attempting to download a very large node structure from the console can trigger an OOM error.
- In thread views, look for
org.onehippo.cm.engine.ConfigurationServiceImpl#exportContentor similar.
HTTP Session Referencing HST Objects
Check if org.apache.catalina.session.StandardSession instances reference HST configuration objects (such as HST links or beans). Storing HST objects in the HTTP session can cause memory leaks.