最近在几个方面进行优化,减少了网站系统运行所占用的内存,内存占用减少了一半,从实践中的得出了几点心得:
- 避免生成新的对象是减少内存使用最有效的办法,生成新的对象的时候有可能在系统各个层面都有可能缓存,减少或者避免数据库查询就能减少大量新对象的生成,避免静态页面在未经改动时生成,或者加大生成的时间间隔,甚至禁用自动生成,提供后台手动生成,新的对象的回收需要一段时间,数据库访问层JPA的缓存也比较大,使用静态页面后这部分缓存完全没有必要,详细检测后发现网站系统各个组件还有大量需要优化的部分和提升的空间。
- 解决内存泄露的问题,在Tomcat中配置检测和阻止内存泄露的listener,能够阻止和检测出来一部分内存泄露,有内存泄露的问题时,日志文件会有提示,可根据提示信息修改系统相关组件代码:
<!-- Prevent memory leaks due to use of particular java/javax APIs--> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
- 系统中能够共享的对象要尽可能共享,这就要求在编写Web程序时,各个组件的状态不依赖特定的状态,在一个Java虚拟机中运行的网站系统,比较重要的是JVM共享,采用static field实现,这就要求JVM共享的对象在应用程序共享的类加载器加载,避免多个类加载器重复加载,另外是应用程序共享,应用程序特定内容可在这个部分进行共享。
- 减少线程数,线程池的配置按照能够需要进行增加,使用jstack pid > jstack.txt输出线程状态信息,查看所分配的线程的运行状态,如果长时间大部分线程空闲,说明此线程池很多线程没用,应减小线程池的空闲数量。
- 调整Java虚拟机垃圾回收期参数,先通过JDK提供的工具对虚拟机进行检测,jps查看进程的PID,jmap -heap pid查看指定进程的内存分配和垃圾回收器的描述,jstat -gc pid 1000 10 对虚拟机的垃圾回收器运行状态和内存状况进行查看,结合系统工具(Linux下)top, free -m查看内存用量。