jvm内存参数设定

在开发java应用时经常出现OutOfMemory的错误,处理了2天,在此做一记录

1.jvm内存结构介绍

http://wenku.baidu.com/view/d82607ea81c758f5f61f67f6.html

 

2.jvm内存监控工具

命令工具:jps、jmap、jstatd

jmap:http://blog.csdn.net/gtuu0123/archive/2010/11/27/6039964.aspx

jstatd:http://blog.csdn.net/gtuu0123/archive/2010/11/21/6025484.aspx

可视化工具:jvmstat、jconsole、jvisualvm

http://j2ee2009.javaeye.com/blog/779068

 

3.jvm参数设定

一般直说设定-Xms, -Xmx等,但没有分情况说明,比如:开发环境Eclipse运行设定、启动tomcat window服务运行的设定

下面这篇说的比较清楚

http://blog.sina.com.cn/s/blog_600448de0100gkzq.html

tomcat6.0除了直接修改注册表外,可以运行%Tomcat_home%/bin/tomcat6w.exe可视化工具进行设置

 

4.健壮代码规则

1) 、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为 null ,暗示垃圾收集器来收集该对象,防止发生内存泄露。

对于仍然有指针指向的实例, jvm 就不会回收该资源 , 因为垃圾回收会将值为 null 的对象作为垃圾,提高 GC 回收机制效率;

 

2) 、我们的程序里不可避免大量使用字符串处理,避免使用 String ,应大量使用 StringBuffer ,每一个 String 对象都得独立占用内存一块区域;

String str = "aaa";

String str2 = "bbb";

String str3 = str + str2;// 假如执行此次之后 str ,str2 以后再不被调用 , 那它就会被放在内存中等待 Java gc 去回收 , 程序内过多的出现这样的情况就会报上面的那个错误 , 建议在使用字符串时能使用 StringBuffer 就不要用 String, 这样可以省不少开销;   

3) 、尽量少用静态变量,因为静态变量是全局的, GC 不会回收的;

 

4) 、避免集中创建对象尤其是大对象, JVM 会突然需要大量内存,这时必然会触发 GC 优化系统内存环境;显示的声明数组空间,而且申请数量还极大。  

这是一个案例

使用 jspsmartUpload 作文件上传 , 运行过程中经常出现 java.outofMemoryError 的错误,

 

检查之后发现问题:组件里的代码

m_totalBytes = m_request.getContentLength();

m_binArray = new byte[m_totalBytes];

问题原因是 totalBytes 这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。解决办法只能换一种更合适的办法,至少是不会引发 outofMemoryError 的方式解决。

参考: http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747

 

jspsmartUpload 为什末要这样作,有他的原因,根据 RFC1867 http 上传标准,得到一个文件流,并不知道文件流的长度。设计者如果想文件的长度,只有操作 servletinputstream 一次才知道,因为任何流都不知道大小。 只有知道文件长度了,才可以限制用户上传文件的长度。为了省去这个麻烦, jspsmartUpload 设计者直接在内存中打开文件,判断长度是否符合标准,符合就写到服务器的硬盘。这样产生内存溢出,这只是我的一个猜测而已。

所以编程的时候,不要在内存中申请大的空间,因为 web 服务器的内存有限,并且尽可能的使用流操作,例如  

    byte[] mFileBody = new byte[512];     
    Blob vField= rs.getBlob("FileBody");     
    InputStream instream=vField.getBinaryStream();     
    FileOutputStream fos=new FileOutputStream(saveFilePath+CFILENAME);     
    int b;     
    while( (b =instream.read(mFileBody)) != -1)  
    {     
        fos.write(mFileBody,0,b);     
    }     
    fos.close();     
    instream.close();  
 

5) 、尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

 

6) 、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使用 hashtable vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次 new 之后又丢弃

 

7) 、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error 的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值

 

 5.扩展Java安全策略

http://dodoflying.javaeye.com/blog/33533

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值