javatomcatmemoryprofilerhttpsession

Measure memory consumption with all HttpSessions in Tomcat at an arbitrary point in time


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 HttpSessions in a running Tomcat instance at an arbitrary point in time without modifying the application?

What I have tried


Solution

  • 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;
        }
    }
    

    enter image description here