欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个Java swing桌面应用程序的JVM内存调优

程序员文章站 2022-05-02 16:02:27
...
背景介绍

       用java swing(jdk 1.7.0_71)开发了一款类似于windows explorer的桌面产品,除了文件管理等常用的功能外,还附带了标签(TAG)管理功能,也就是对文件或者文件夹指定标签,根据标签对文件进行管理.

 

遇到的问题

       应用中有一个根据关键字进行文件查找的功能,查找本身并没有什么问题,只是对符合查找条件的文件或者文件夹进行画面显示的时候,遇到了jvm内存爆满的问题.因为测试了一种极端的情况,查找C盘下的所有带a关键字的文件和文件夹,因为结果集特别大,所以画面显示的时候遭遇了JVM内存储爆满.

 

原因分析

       结果集显示的时候,其实就是往JPanel里面不断地add新的文件JPanel,一个文件JPanel里面至少有两个JLabel,一个用来显示图标,另一个显示文件名,所有的这些对象都在不断地向JVM堆里面涌动,而且这些对象在切换到别的画面之前,都不会被JVM回收.这样就造成了JVM内存储爆满.

 

整个过程如下:

 

1>缺省配置启动java,最大堆内存为247.5M,这个数值是绝对不够用的

因为

NewRatio=2 default

SurvivorRatio=8 default

 

所以

Eden space=64M

Survivor space=8M

Tenured gen=175.5M

最终结果如下:

 

 

Console报错:

Exception in thread "RMI TCP Connection(idle)" Exception in thread "RMI TCP Connection(idle)" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Exception in thread "JMX server connection timeout 23" java.lang.OutOfMemoryError: Java heap space

java.lang.NullPointerException

at sun.awt.SunToolkit.postEvent(SunToolkit.java:473)

at sun.awt.windows.WComponentPeer.postEvent(WComponentPeer.java:849)


一个Java swing桌面应用程序的JVM内存调优
            
    
    博客分类: JVMJava编程 jvmcmsswingjconsoleOutOfMemoryError 
 

2>把最大堆内存调整到上限1024M

-XX:+PrintGCDetails  -Xms1024m -Xmx1024m

实际获得的heap合计:990M

因为

NewRatio=2 default

SurvivorRatio=8 default

 

所以

Eden space=273M

Survivor space=34M

Tenured gen=683M

最终,成功执行完查找操作,只是很勉强(Tenured gen只剩下了1K)

 

结果如下:

 

一个Java swing桌面应用程序的JVM内存调优
            
    
    博客分类: JVMJava编程 jvmcmsswingjconsoleOutOfMemoryError 
 

3>从2>的结果可以看出,问题的关键在于Tenured gen的空间大小,尽可能地把空间分给Tenured gen是解决问题的关键,于是,我们可以追加-XX:NewRatio参数来调大Tenured gen的空间,比如:

 

-XX:+PrintGCDetails  -Xms1024m -Xmx1024m -XX:NewRatio=4

因为绝大部分对象都是无法回收的,所以为了降低gc时间,其实我们也可以通过调大-XX:SurvivorRatio的值,变相拿掉Survivor space,比如:

-XX:+PrintGCDetails  -Xms1024m -Xmx1024m -XX:NewRatio=4  -XX:SurvivorRatio=65536

 

4>之前使用的gc属于单线程的serial collector,比较适合于单机,如果想尝试一下CMS并发收集器的话,也是可以的,虽然必要性不大

-XX:+PrintGCDetails  

-Xms1024m -Xmx1024m

-Xmn200m                                  直接指定年轻代大小,也可以通过-XX:NewRatio调节

-XX:SurvivorRatio=65536           变相去掉Survivor space

-XX:+UseConcMarkSweepGC    使用CMS内存收集

-XX:ReservedCodeCacheSize=10m            尽可能节省空间

-XX:MaxPermSize=20m                               尽可能节省空间

-XX:+CMSScavengeBeforeRemark        强制remark之前开始一次minor gc,减少remark的暂停时间,不过我们这种情况没有必要加,因为大部分对象都不会被gc掉

-XX:+UseCMSInitiatingOccupancyOnly        为了配合CMSInitiatingOccupancyFraction使用,不指定的话,jvm根据历史数据自动判断什么时候进行gc

-XX:CMSInitiatingOccupancyFraction=95    Tenured gen代使用空间达到95%才进行gc

 


一个Java swing桌面应用程序的JVM内存调优
            
    
    博客分类: JVMJava编程 jvmcmsswingjconsoleOutOfMemoryError 
 

  • 一个Java swing桌面应用程序的JVM内存调优
            
    
    博客分类: JVMJava编程 jvmcmsswingjconsoleOutOfMemoryError 
  • 大小: 108.2 KB
  • 一个Java swing桌面应用程序的JVM内存调优
            
    
    博客分类: JVMJava编程 jvmcmsswingjconsoleOutOfMemoryError 
  • 大小: 99.1 KB
  • 一个Java swing桌面应用程序的JVM内存调优
            
    
    博客分类: JVMJava编程 jvmcmsswingjconsoleOutOfMemoryError 
  • 大小: 80.9 KB