I want to measure the percentage of memory used by HttpSession
in a web application.
Is there any way to measure memory consumption with all HttpSession
s in a running Tomcat instance at an arbitrary point in time without modifying the application?
HttpSession
is org.apache.catalina.session.StandardSession
. I have profiled the application with VisualVM and specified org.apache.catalina.session.StandardSession
in [Profiler]-[Memory settings]
. But it shows only the size of StandardSession
itself (the size of ConcurrentHashMap
contained in StandardSession
is not included).HttpSession
.org.apache.catalina.session.ManagerBase#findSessions()
and measure the size of HttpSession
s with Byteman and SizeOf.deepSizeOf()
. But this Byteman rule runs only when a new HttpSession
is created. I want measure memory consumption with HttpSession
s at an arbitrary point in time (e.g. in every 30 seconds).According to the comment from @LMC, I made a sample project to get the size of HttpSession with JMX: https://github.com/satob/SessionSize
Note that because you cannot access org.apache.catalina.session.ManagerBase
directly, this project uses ByteMan. Store the ManagerBase
object to a static field of the MBean SessionMonitor
with Byteman like:
RULE Set ManagerBase object to MBean
CLASS ^org.apache.catalina.session.ManagerBase
METHOD initInternal
AT EXIT
IF TRUE
DO
traceln("SETTING SessionManager");
com.example.sessionsize.SessionMonitor.setSessionManager($this);
ENDRULE
and use it in the JMX interface like:
package com.example.sessionsize;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import net.sourceforge.sizeof.SizeOf;
public class SessionMonitor implements SessionMonitorMBean {
private static Manager sessionManager = null;
public static void setSessionManager(Manager manager) {
sessionManager = manager;
}
@Override
public long getMemoryConsumption() {
if (sessionManager != null) {
try {
Session [] sessions = sessionManager.findSessions();
return SizeOf.deepSizeOf(sessions);
} catch(RuntimeException e) {
// Falied to get size of HttpSession object
e.printStackTrace();
return -2;
}
} else {
// SessionManager is not ready
return -1;
}
}
@Override
public long getNumberOfActiveHttpSession() {
return sessionManager.findSessions().length;
}
}