大数据存session致内存泄露解决方案

一、前因

一份大数据,在用户登录时生存新session,并存进去,而session timeout设为了5h

 

二、过程

1、找进程

root@rise-vm-244:/usr/local/resin/conf# jps
9613 WatchdogManager
17028 Jps
9660 Resin

 2、找进程所属用户

ps -ef | grep 9660
www-data  9660  9613  7 00:33 ?        00:09:44 /usr/local/jrockit-R2

 3、参看java命令相关参数

root@rise-vm-244:/usr/local/resin/conf# java -X
    -Xbootclasspath:<directories and zip/jar files separated by :>
              set search path for bootstrap classes and resources
    -Xbootclasspath/a:<directories and zip/jar files separated by :> 
              append to end of bootstrap class path
    -Xbootclasspath/p:<directories and zip/jar files separated by :>
              prepend in front of bootstrap class path
    -Xgcprio:[throughput|pausetime|deterministic]
              sets priority for the garbage collector (gc)
                  throughput    optimizes the gc behavior to achieve optimal
                                throughput (default in server mode)
                  pausetime     optimizes the gc behavior to achieve minimal
                                pause times 
                  deterministic optimizes the gc behavior to ensure extremely
                                short pause times and limit the total number of
                                those pauses within a prescribed window (this
                                feature requires a valid license)

 

root@rise-vm-244:/usr/local/resin/conf# jrcmd -h
Usage: <jrockit pid> [<command> [<arguments>]] [-l] [-f file]     
   or: -p                                                         
   or: -h                                                         
                                                                  
  <command> is a valid JRockit command. Try "help".             
  If the pid is 0, commands will be sent to all JRockit processes.
  If no options are given, lists JRockit processes (same as -p).  
                                                                  
  -l  display the counters exposed by this process                
  -f  read and execute commands from the file                     
  -p  list JRockit processes on the local machine                 
  -h  this help                                      

 

root@rise-vm-244:/usr/local/resin/conf# sudo -u www-data jrcmd 9660 help
9660:
The following commands are available:
        kill_rmp_server
        start_rmp_server
        kill_management_server
        start_management_server
        checkjrarecording
        stopjrarecording
        startjrarecording
        print_object_summary
        memleakserver
        print_codegenlist
        print_class_summary
        run_optfile
        dump_codelayout
        dump_codelist
        dump_codemap
        print_utf8pool
        print_properties
        print_threads
        datadump_request
        runsystemgc
        runfinalization
        heap_diagnostics
        oom_diagnostics
        print_exceptions
        version
        timestamp
        command_line
        sanity
        verbosity
        set_filename
        help
        print_memusage

 

root@rise-vm-244:/usr/local/resin/conf# sudo -u www-data jrcmd 9660 print_object_summary
9660:

--------- Detailed Heap Statistics: ---------
30.8% 18851k   223771  -2884k [C
15.9% 9698k     2061   -171k [B
 6.7% 4073k   173796  -1799k java/lang/String
 5.4% 3283k   105069  -3036k java/util/LinkedHashMap$Entry
 4.6% 2823k    54897  -1854k [Ljava/util/HashMap$Entry;
 4.1% 2491k   106286  -1764k java/util/HashMap$Entry
 2.9% 1766k    56516     +0k com/caucho/loader/JarMap$JarList
 2.4% 1456k    31072  -1010k java/util/HashMap
 2.2% 1344k    21514  -1341k org/springframework/util/LinkedCaseInsensitiveMap
 2.1% 1309k       39     +0k [Lcom/caucho/util/LruCache$CacheItem;
 1.8% 1082k     9234     -8k java/lang/Class
 1.6% 1006k    14587   -146k [Ljava/lang/Object;
 1.3% 795k    10184   -188k java/lang/reflect/Method
 0.9% 580k    14861     +0k java/lang/ref/WeakReference
 0.6% 394k     8422     -3k java/lang/ref/SoftReference
 0.6% 371k    47563     +0k java/lang/Object
 0.6% 361k     9250     +0k com/caucho/util/LruCache$CacheItem
 0.6% 342k    21947   -335k java/util/HashMap$EntrySet
 0.5% 308k     4928   +231k com/mysql/jdbc/ConnectionPropertiesImpl$BooleanConnectionProperty
     61148kB total ---

--------- End of Detailed Heap Statistics ---

 

按最大对象查找工程代码,无果,细看代码,发现竟将大数据存进了session

 

三、解决办法

1、用Map<String, BigObject>:用户ID,大数据对象

2、用户每次登录,重写Map对象中的BigObject

3、BigObject有一个用户最后活跃时间字段,用户请求每次经过Filter,都用new Date()更新

4、另起一个定时线程,删除超时的BigObject

public class PrivilegeScheduler {
	private static final long RELOAD_DELAY = 1000L * 60 * 1;
	private static final long RELOAD_PERIOD = 1000L * 60 * 30;
	private static final long TIMEOUT_PERIOD = 1000L * 60 * 30;
	private static ScheduledExecutorService es = Executors.newScheduledThreadPool(5);

	/**
	 * 定时清理缓存
	 */
	public static void schedule() {
		es.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				PrivilegeCache.removeTimeOutUserPrivilege(TIMEOUT_PERIOD);
			}
		}, RELOAD_DELAY, RELOAD_PERIOD, TimeUnit.MILLISECONDS);
	}
}

 5、定时线程,通过Listener,系统启动时启动

<listener>
    <description>用于实始化系统参数</description>
    <listener-class>com.package.company.common.web.listener.ServletContextInitListener</listener-class>
</listener>

 

public class ServletContextInitListener implements ServletContextListener {
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getAutowireCapableBeanFactory().autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME,false);
		PrivilegeScheduler.schedule();
	}	
}

 

你可能感兴趣的:(session)