We are building xPages applications on Domino 8.5.2 that use custom Java Beans, and from time to time the dev server encounters a java/lang/OutOfMemoryError. It all works fine again after the http task is restarted, but of course this is an absolute killer if it happens on a customer's server. So I had a look at the heapdumps in Eclipse Memory Analysis, and checking for the top consumers I get this:
Obviously the class BCCPropertyStore is instanciated so often that it makes up 20% of the entire heap, although it is supposed to be singleton. The class begins like this:
public class BCCPropertyStore {
// Constants
private static final String CLASS_NAME = "BCCPropertySynch ";
private static BCCPropertyStore instance = new BCCPropertyStore();
...
public static BCCPropertyStore getInstance() {
return instance;
}
And every time it is used we call it with BCCPropertyStore.getInstance(), which is static, so my understanding is that there should not be multiple instances of it (the Java beans usually are in application scope, so I don't see why they should have multiple instances either). However, if I look at the duplicate classes it is striking that there also a lot of xPages-classes appearing much more often than they should:
There are no thousands of users logging into the application for whom all these instances could have been created, just me and a fellow developer. HTTPJVMMaxHeapSize is set to 256M, which in theory should be more than sufficient for an application of the size of this one.
Why is the JVM creating so many useless instances of classes until it runs out of memory, and why are they not snuffed out by the garbage collector? Is this an xPages-specific issue or did I miss something?
UPDATE
Today the error occured again and I am no wiser. I changed BCCPropertyStore into enum as suggested below, obviously that didn't change anything as the heap dump looks pretty much the same as in the screenshots I posted before.
Is there any tool with which we can monitor the memory usage of the JVM while it is running, or something similar which helps us to determine if the fixes and suggestions are working or not?
Here is the stacktrace:
2013-05-07T10:44:32.441+02:00 java.lang.RuntimeException: com.ibm.xsp.FacesExceptionEx: java.lang.OutOfMemoryError at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:433) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initModule(NSFComponentModule.java:427) at com.ibm.domino.xsp.module.nsf.NSFService.loadModule(NSFService.java:561) at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:521) at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:342) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:304) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:261) at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:291) Caused by: com.ibm.xsp.FacesExceptionEx: java.lang.OutOfMemoryError at com.ibm.xsp.config.CLBootStrap.initContext(CLBootStrap.java:73) at com.ibm.xsp.config.BootStrap.init(BootStrap.java:60) at com.ibm.xsp.config.ConfigureCoreListener.contextInitialized(ConfigureCoreListener.java:58) at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:425) ... 7 more Caused by: java.lang.OutOfMemoryError at java.util.Hashtable.newEntry(Hashtable.java:91) at java.util.Hashtable.put(Hashtable.java:766) at java.util.PropertyPermissionCollection.add(PropertyPermissionCollection.java:40) at java.security.Permissions.add(Permissions.java:98) at org.apache.harmony.security.fortress.PolicyUtils.toPermissionCollection(PolicyUtils.java:541) at org.apache.harmony.security.fortress.DefaultPolicy.getPermissions(DefaultPolicy.java:242) at org.apache.harmony.security.fortress.DefaultPolicy.implies(DefaultPolicy.java:365) at java.security.ProtectionDomain.implies(ProtectionDomain.java:159) at java.security.AccessController.checkPermission(AccessController.java:98) at java.lang.SecurityManager.checkPermission(SecurityManager.java:533) at org.eclipse.osgi.framework.internal.core.Framework.checkAdminPermission(Framework.java:1299) at org.eclipse.osgi.framework.internal.core.BundleHost.getResource(BundleHost.java:266) at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:84) at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:103) at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:103) at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:67) at com.ibm.domino.xsp.module.nsf.NotesClientClassLoader.getResource(NotesClientClassLoader.java:130) at java.lang.ClassLoader.getResource(ClassLoader.java:438) at com.ibm.domino.xsp.module.nsf.ModuleClassLoader.getResource(ModuleClassLoader.java:117) at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:503) at javax.xml.parsers.SecuritySupport$4.run(Unknown Source) at java.security.AccessController.doPrivileged(AccessController.java:202) at javax.xml.parsers.SecuritySupport.getResourceAsStream(Unknown Source) at javax.xml.parsers.FactoryFinder.findJarServiceProvider(Unknown Source) at javax.xml.parsers.FactoryFinder.find(Unknown Source) at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source) at org.apache.commons.digester.Digester.getFactory(Digester.java:512) at org.apache.commons.digester.Digester.getParser(Digester.java:686) at org.apache.commons.digester.Digester.getXMLReader(Digester.java:902) at org.apache.commons.digester.Digester.parse(Digester.java:1548) at com.sun.faces.config.ConfigureListener.parse(ConfigureListener.java:1229) at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:328) at com.ibm.xsp.config.CLBootStrap.initContext(CLBootStrap.java:65) ... 10 more 2013-05-07T10:44:33.879+02:00 java.lang.OutOfMemoryError at java.util.HashMap.newElementArray(HashMap.java:282) at java.util.HashMap.rehash(HashMap.java:686) at java.util.HashMap.rehash(HashMap.java:730) at java.util.HashMap.putImpl(HashMap.java:611) at java.util.HashMap.put(HashMap.java:605) at com.ibm.domino.xsp.module.nsf.RuntimeFileSystem.refresh(RuntimeFileSystem.java:269) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initNSFData(NSFComponentModule.java:565) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doInitModule(NSFComponentModule.java:439) at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:412) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initModule(NSFComponentModule.java:427) at com.ibm.domino.xsp.module.nsf.NSFService.loadModule(NSFService.java:561) at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:439) at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:342) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:304) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:261) at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:291) 2013-05-07T10:46:17.582+02:00 java.lang.OutOfMemoryError at java.util.HashMap.newElementArray(HashMap.java:282) at java.util.HashMap.rehash(HashMap.java:686) at java.util.HashMap.rehash(HashMap.java:730) at java.util.HashMap.putImpl(HashMap.java:611) at java.util.HashMap.put(HashMap.java:605) at com.ibm.domino.xsp.module.nsf.RuntimeFileSystem.refresh(RuntimeFileSystem.java:269) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initNSFData(NSFComponentModule.java:565) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doInitModule(NSFComponentModule.java:439) at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:412) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initModule(NSFComponentModule.java:427) at com.ibm.domino.xsp.module.nsf.NSFService.loadModule(NSFService.java:561) at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:439) at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:342) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:304) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:261) at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:291)