title: Confusion related enum object allocation in JVM
body: <p>This might be a stupid question, but I am really confused after Googling. </p>
  
  <p>We have a very big Java EE application. Now when it's time to go to production, there are a number of performance related problems raised. I am trying to get to the bottom of a memory leak issue. When I was looking through JProfiler, I found some enum variables that will not be garbage collected. </p>
  
  <p>Just an example:</p>
  
  <p>The application has one session factory, which is a kind of map i.e. <code>Map&lt;SessionKey, Object&gt;</code>. When the user is logged in that map will fill up and it will be cleared when that user logs out. </p>
  
  <p>But with JProfiler I encountered some strange behavior. It shows <code>SessionKey</code> memory allocation  increasing with the number of logins. When I'm logged in for the first time it shows <strong>106 difference</strong> and after the second login it shows <strong>206 difference</strong> in JProfiler. So this means the difference is increasing and increases more frequently.</p>
  
  <p><strong>is it enum never eligible for garbage collection?</strong></p>
  
  <p>I could not get it that what is wrong in it. Or I understand wrong. Let me know for more detail.</p>
  
  <pre><code>public enum SessionKey{
      LOGGEDIN_USER, DOCUMENT_ID, LOGGEDIN_USER_POSTS, LOGGEDIN_USER_PRIVILEGE, NORM_ID, DOCUMENT_REF_NO,DOCUMENT_STATUS, DOCUMENT,APPLICANT_USER, 
      NORM, CLIENT_SESSION_EXPIRED,  
      GININJECTOR, SCHEDULE_ID, DOCUMENT_ENTITY_TYPE,SOURCE_DOCUMENT_ID, CONFIGURATION_LIST, LOGGEDIN_USER_ID, 
      SOURCE_NORM_ID, MASKING_PANEL, IS_ETOKEN, 
      LOGGEDIN_USER_PRIVILEGE_NAMES, LOGGEDIN_USER_PRIVILEGE_IDS, IPADDRESS, AUTO_COMPLETE_SCHEDULER,
      MESSAGES, DEFAULT_CERTIFICATE, DOCUMENT_FORM_MAP,DOCUMENT_FORM_FCM_MAP,DOCTYPELIST,ACCESS_RIGHT,LOGGEDIN_USER_DEFAULT_POST,LAST_LOGIN_DETAILS, DOC_STATUS_ENUM_MASTERS
      ,MODULE_RIGHT_ENUM_MASTERS,MODULE_RIGHT, LOGGEDIN_USER_DEFAULT_PORTAL,
      LOGGEDIN_USER_DEFAULT_POST_MAP,HISTORY_CLEAR,DOC_DETAILS_PORTAL,ORGANIZATION_ID, DOCUMENT_DETAILS_FROM_JSP,PORTAL_MAP,ORGANIZATION,
      CONFIGURATION_MAP, DEFAULT_SIGN_CERTIFICATE,SYSTEM_VERSION,
      IS_LOGGEDIN_IN_ORGANIZATION, SUPPLIER_PORTAL_BASED_ON_URL, SUPPLIER_ORGANIZATION_BASED_ON_URL, BEFORE_LOGIN, USER_LANGUAGE, SERVER_DATE_TIME,DOCUMENTTYPE_CONFIG_TABLE;
  }
  </code></pre>
  
  <p>SessionFacory code:</p>
  
  <pre><code>public class SessionFactory {
      private static HashMap session;
      public static HashMap getClientSessionInstance() {
          if (session == null) {
              session = new HashMap();
          }
          return session;
      }
  
      public static Object getValue(SessionKey key) {
          return getClientSessionInstance().get(key);
      }
  
      public static void putValue(SessionKey key, Object value) {
  
          getClientSessionInstance().put(key, value);
      }
  
      public static void remove(SessionKey key) {
          getClientSessionInstance().remove(key);
      }
  
      public static void clear() {
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER);
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER_PRIVILEGE);
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER_ID);
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER_POSTS);
          getClientSessionInstance().remove(SessionKey.CONFIGURATION_LIST);
          getClientSessionInstance().remove(SessionKey.DOCUMENTTYPE_CONFIG_TABLE);
          getClientSessionInstance().remove(SessionKey.SERVER_DATE_TIME);
          getClientSessionInstance().remove(SessionKey.USER_LANGUAGE);
          getClientSessionInstance().remove(SessionKey.SUPPLIER_ORGANIZATION_BASED_ON_URL);
          getClientSessionInstance().remove(SessionKey.SUPPLIER_PORTAL_BASED_ON_URL);
          getClientSessionInstance().remove(SessionKey.IS_LOGGEDIN_IN_ORGANIZATION);
          getClientSessionInstance().remove(SessionKey.DEFAULT_SIGN_CERTIFICATE);
          getClientSessionInstance().remove(SessionKey.CONFIGURATION_MAP);
          getClientSessionInstance().remove(SessionKey.ORGANIZATION);
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER_DEFAULT_PORTAL);
  
          getClientSessionInstance().remove(SessionKey.ACCESS_RIGHT);
          getClientSessionInstance().remove(SessionKey.DOC_STATUS_ENUM_MASTERS);
          getClientSessionInstance().remove(SessionKey.IS_ETOKEN);
  
          getClientSessionInstance().remove(SessionKey.ORGANIZATION_ID);
  
          getClientSessionInstance().remove(SessionKey.LAST_LOGIN_DETAILS);
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER_DEFAULT_POST);
          getClientSessionInstance().remove(SessionKey.MODULE_RIGHT);
          getClientSessionInstance().remove(SessionKey.MASKING_PANEL);
          getClientSessionInstance().remove(SessionKey.GININJECTOR);
          getClientSessionInstance().remove(SessionKey.MODULE_RIGHT_ENUM_MASTERS);
          getClientSessionInstance().remove(SessionKey.LOGGEDIN_USER_DEFAULT_POST_MAP);
  
  
          clearDocumentSession();
  
      }
  
      public static void clearDocumentSession() {
          getClientSessionInstance().remove(SessionKey.DOCUMENT_ID);
          getClientSessionInstance().remove(SessionKey.DOCUMENT_REF_NO);
          getClientSessionInstance().remove(SessionKey.DOCUMENT_STATUS);
          getClientSessionInstance().remove(SessionKey.DOCUMENT);
          getClientSessionInstance().remove(SessionKey.APPLICANT_USER);
          getClientSessionInstance().remove(SessionKey.NORM);
          getClientSessionInstance().remove(SessionKey.NORM_ID);
          getClientSessionInstance().remove(SessionKey.SCHEDULE_ID);
          if(getClientSessionInstance().containsKey(SessionKey.SOURCE_DOCUMENT_ID))
              getClientSessionInstance().remove(SessionKey.SOURCE_DOCUMENT_ID);
          if(getClientSessionInstance().containsKey(SessionKey.SOURCE_NORM_ID))
              getClientSessionInstance().remove(SessionKey.SOURCE_NORM_ID);
      }
  
  }
  </code></pre>