- 浏览: 862586 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (687)
- java (127)
- servlet (38)
- struts (16)
- spring (22)
- hibernate (40)
- javascript (58)
- jquery (18)
- tomcat (51)
- 设计模式 (6)
- EJB (13)
- jsp (3)
- oracle (29)
- RUP (2)
- ajax (3)
- java内存管理 (4)
- java线程 (12)
- socket (13)
- path (5)
- XML (10)
- swing (2)
- UML (1)
- JBPM (2)
- 开发笔记 (45)
- Note参考 (15)
- JAXB (4)
- Quartz (2)
- 乱码 (2)
- CSS (2)
- Exception (4)
- Tools (7)
- sqlserver (3)
- DWR (7)
- Struts2 (47)
- WebService (2)
- 问题解决收藏 (7)
- JBOSS (7)
- cache (10)
- easyUI (19)
- jQuery Plugin (11)
- FreeMarker (6)
- Eclipse (2)
- Compass (2)
- JPA (1)
- WebLogic (1)
- powerdesigner (1)
- mybatis (1)
最新评论
-
bugyun:
受教了,谢谢
java 正则表达式 过滤html标签 -
xiongxingxing_123:
学习了,感谢了
java 正则表达式 过滤html标签 -
wanmeinange:
那如果无状态的。对同一个任务并发控制怎么做?比如继承Quart ...
quartz中参数misfireThreshold的详解 -
fanjieshanghai:
...
XPath 元素及属性查找 -
tianhandigeng:
还是没明白
quartz中参数misfireThreshold的详解
JVM的内存优化
- 博客分类:
- tomcat
自:http://hi.baidu.com/waltertan/blog/item/a7ef522a00cfff285243c100.html
关于java.lang.OutOfMemoryError:Java Heap Space
当一个Java应用程序在对大批量数据进行操作时,JVM很容易抛出java.lang.outOfMemoryError:Java Heap Space的错误,即堆栈中的内存用光。
产生OutOfMemoryError的原因
JVM抛出这种错误的原因,一是程序代码本身不够严谨,产生大量的垃圾,甚至因对象使用完没有立即给它的引用赋空值,导致对象在内存堆积而无法释放(在循环语句中特别如此),这中错误是可以避免的;二是JVM分配的内存值相对过少,导致Java程序无法运行。
针对原因一,由于jvm产生的垃圾是由我们所写的代码产生的,质量好的代码产生的垃圾少,相反就会产生很多垃圾。由于jvm的最大内存不能无限增大,故增大jvm的最大内存应该是在代码已经达到很优化时才实施的,所以优化程序才是我们最先要做的。
如何优化程序:
第一,避免死循环。仔细检查程序,防止出现死循环,这是比较容易检查的。
第二,可以适当手动回收垃圾,即使调用System.gc()或Runtime.gc()。
第三,应该及时释放种资源:内存, 数据库的各种连接。释放资源的时候不能依赖于java的垃圾自动回收机制,最好也不要用finalize方法,因为无用单元回收不是一个完全可以确定的过程,作为低优先级进程,往往是系统没有内存时才调用垃圾回收进程。
针对原因二,应增加JVM的内存大小。JVM运行时候占用一定的内存,其大小是有限定的,如果程序在运行时JVM占用的内存大于某个限度,则会产生内存益处,也就是java.lang.outofmemoryerror。
增加JVM的内存需要设置一些参数
一般来讲,设置JVM的堆栈内存会涉及到下面四个参数:
-XX:PermSize 设置非堆内存初始大小,如-XX:PermSize=56m,默认是物理内存的1/6;
-XX:MaxPermSize 设置最大非堆内存的大小,如-XX:MaxPermSize=128m,默认是物理内存的1/4;
如何设置JVM内存分配?
查看JVM使用的内存情况
Runtime.getRuntime().maxMemory(); //最大可用内存,对应-Xmx
Runtime.getRuntime().freeMemory(); //当前JVM空闲内存
Runtime.getRuntime().totalMemory(); //当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和
关于maxMemory(),freeMemory()和totalMemory():
maxMemory()为JVM的最大可用内存,可通过-Xmx设置,默认值为物理内存的1/4,设值不能高于计算机物理内存;
totalMemory()为当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和,会随着JVM使用内存的增加而增加;
freeMemory()为当前JVM空闲内存,因为JVM只有在需要内存时才占用物理内存使用,所以freeMemory()的值一般情况下都很小,而JVM实际可用内存并不等于 freeMemory(),而应该等于maxMemory()-totalMemory()+freeMemory()。及其设置JVM内存分配。
关于GC(垃圾回收)
在一些规模稍大的应用中,JVM的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步。
PermGen space:全称是Permanent Generation space.就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域Heap space:存放Instance。
GC(Garbage Collection)应该不会对PermGen space进行清理,所以如果你的APP会LOAD很多class的话,就很可能出现PermGen space错误。
Java Heap分为3个区
1.Young
2.Old
3.Permanent
Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文不讨论该区。
JVM的Heap分配可以使用-X参数设定:
-Xms 初始Heap大小
-Xmx java heap最大值
-Xmn young generation的heap大小
JVM有2个GC线程
第一个线程负责回收Heap的Young区
第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区
Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。
为什么一些程序频繁发生GC?
有如下原因:
1.程序内调用了System.gc()或Runtime.gc()。
2.一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC。
3.Java的Heap太小,一般默认的Heap值都很小。
4.频繁实例化对象,Release对象 此时尽量保存并重用对象,例如使用StringBuffer()和String()。
如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态,许多Server端的Java程序每次GC后最好能有65%的剩余空间
JVM调优的经验之谈:
1.Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3。
2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成。
注意:
1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。
2.Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。
Stack的设定
每个线程都有他自己的Stack。
-Xss
每个线程的Stack大小
Stack的大小限制着线程的数量。如果Stack过大就好导致内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K。如果Stack太小,也会导致Stack溢漏。
硬件环境
硬件环境也影响GC的效率,例如机器的种类,内存,swap空间,和CPU的数量。
如果你的程序需要频繁创建很多transient对象,会导致JVM频繁GC。这种情况你可以增加机器的内存,来减少Swap空间的使用。
4种GC
1、第一种为单线程GC,也是默认的GC,该GC适用于单CPU机器。
2、第二种为Throughput GC,是多线程的GC,适用于多CPU,使用大量线程的程序。第二种GC与第一种GC相似,不同在于GC在收集Young区是多线程的,但在Old区和第一种一样,仍然采用单线程。-XX:+UseParallelGC参数启动该GC。
3、第三种为Concurrent Low Pause GC,类似于第一种,适用于多CPU,并要求缩短因GC造成程序停滞的时间。这种GC可以在Old区的回收同时,运行应用程序。-XX:+UseConcMarkSweepGC参数启动该GC。
4、第四种为Incremental Low Pause GC,适用于要求缩短因GC造成程序停滞的时间。这种GC可以在Young区回收的同时,回收一部分Old区对象。-Xincgc参数启动该GC。
设置服务器JVM内存
在catalina.bat最前面加入set JAVA_OPTS=-Xms128m -Xmx350m。如果用startup.bat启动tomcat,OK设置生效,能够成功的分配200M内存。但是如果不是执行startup.bat启动tomcat而是利用windows的系统服务启动tomcat服务,上面的设置就不生效了,就是说set JAVA_OPTS=-Xms128m -Xmx350m没起作用,上面分配200M内存就OutOfMemory了。windows服务执行的是bin\tomcat.exe.他读取注册表中的值,而不是 catalina.bat的设置。 解决办法: 修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Tomcat Service Manager\Tomcat5\Parameters\JavaOptions 原值为 -Dcatalina.home="C:\ApacheGroup\Tomcat 5.0" 重起tomcat服务,设置生效。
JBoss启动JVM内存设置 默认可以使用的内存为64MB Eclipse启动JVM内存设置 在所在目录下,键入 Websphere启动JVM内存设置 进入控制台去设置:应用程序服务器 > server1 > 进程定义 > Java 虚拟机
-Djava.endorsed.dirs="C:\ApacheGroup\Tomcat 5.0\common\endorsed"
-Xrs加入 -Xms300m -Xmx350m
$JBOSSDIR$/bin/run.config
JAVA_OPTS = "-server -Xms128 -Xmx512"
eclipse.exe -vmargs -Xms256m -Xmx512m
256m表示JVM堆内存最小值
512m表示JVM堆内存最大值
参考资料:
WebLogic启动JVM内存设置
在weblogic中,可以在startweblogic.cmd中对每个domain虚拟内存的大小进行设置,默认的设置是在commEnv.cmd里面。
http://blog.csdn.net/cool_rain_man/archive/2010/10/12/5935426.aspx
http://www.verybc.com/a/hulianwang/2009/1124/8839.html
http://cache.baidu.com/c?m=9d78d513d99b12eb0bfa940f5051913b4d0bd73c61979b423f94ce0887231b1f483ca5fd65351177ced82c395cfa5e5c9df33273200357e6c697950b87e0d77f74df78672b42914710d019abd6167b9c758d1baffc5fbcebed3191a9d2d7dd5f53c851007983f08e510612c96ef01634fe&p=b47e8316d9c533ec08e292755355&user=baidu
-Xmx 设置Java Heap最大值,如-Xmx128m,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定;
-Xms 设置Java Heap初始值,如-Xms64m,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;
-Xmn 设置Java Heap Young区大小,如-Xmn32m,不熟悉最好保留默认值;
-Xss 设置每个线程的Stack大小,如-Xss16m,不熟悉最好保留默认值;
还有两个参数是跟非堆栈内存有关的:
Tomcat启动JVM内存设置:
一、Linux
在/usr/local/apache-tomcat-5.5.23/bin目录下的catalina.sh添加:JAVA_OPTS='-Xms512m -Xmx1024m'要加“m”说明是MB,否则就是KB了,在启动tomcat时会报内存不足。
-Xms:初始值
-Xmx:最大值
-Xmn:最小值
二、Windows
另外,在程序运行的过程中,我们也可以调用以下方法查看JVM使用的内存情况:
一、当在命令提示符下启动并使用JVM时:
java -Xms256m -Xmx512m -XX:MaxPermSize=512m
java -Xmx128m -Xms64m -Xmn32m -Xss16m Test(只对当前运行的类Test生效)
二、当在集成开发环境下(如eclipse/MyEclipse)启动并使用JVM时有三种方法:
方法1: 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配):
-vmargs
-vmargs表示以下为虚拟机设置参数,可修改其中的参数值,也可添加-Xmn,-Xss,另外,eclipse.ini内还可以设置非堆内存,如:-XX:PermSize=56m,-XX:MaxPermSize=128m。
此处设置的参数值可以通过以下配置在开发工具的状态栏显示:
在eclipse根目录下创建文件options,文件内容为:org.eclipse.ui/perf/showHeapStatus=true
修改eclipse根目录下的eclipse.ini文件,在开头处添加如下内容:
-debug
重新启动eclipse,就可以看到下方状态条多了JVM信息。
方法2:打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效)
编辑当前使用的JRE,在缺省VM参数中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m
方法3: 打开eclipse-运行-运行-Java应用程序(只对所设置的java类生效)
选定需设置内存分配的类-自变量,在VM自变量中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m
注:如果在同一开发环境中同时进行了b和c设置,则b设置生效,c设置无效,如:
开发环境的设置为:-Xmx256m,而类Test的设置为:-Xmx128m -Xms64m,则运行Test时生效的设置为:
-Xmx256m -Xms64m
三、当在服务器环境下(如Tomcat)启动并使用JVM时(对当前服务器环境下所以Java程序生效):
方法1:设置环境变量
变量名:CATALINA_OPTS
变量值:-Xmx128m -Xms64m -Xmn32m -Xss16m
方法2:打开Tomcat根目录下的bin文件夹,编辑catalina.bat,将其中的%CATALINA_OPTS%(共有四处)替换为:-Xmx128m -Xms64m -Xmn32m -Xss16m
发表评论
-
JVM最大分配内存
2012-06-21 12:27 1077分析了当前比较流行的几个不同公司不同版本JVM的最大内存,得出 ... -
查看jvm最大内存
2012-06-21 12:22 1445查看jvm最大内存 java -Xmx1500M -vers ... -
Tomcat内存设置 .
2012-06-15 23:03 988Tomcat 内存配置 2009年08月11日 17:05 ... -
如何指定tomcat中session过期时间
2012-06-06 11:33 790如何指定tomcat中session过期时间 1. 在se ... -
负载均衡环境中和如何设置Expires和Etag .
2012-06-12 09:56 1484在负载均衡环境中(LVS, LoadBalance)为了减少浏 ... -
轻松实现Apache,Tomcat集群和负载均衡
2012-06-05 23:24 1011作者:罗代均 ldj_work#126.com,转载请保持完整 ... -
tomcat最多能支持多少用户
2012-06-05 23:20 2699Tomcat里用线城池来控制并发用户的个数。 初始化为150个 ... -
tomcat开启Gzip
2011-04-08 23:52 1228现在来说一下如何在TOM猫中一步到位(要求TOM猫5.0以后版 ... -
tomcat的虚拟站点问题
2011-03-02 14:50 1327<Host name="localhost&q ... -
Tomcat里 appBase和docBase的区别
2011-03-02 14:47 1223<host appBase="d:/aaa&q ... -
Apache+Tomcat负载均衡和集群的尝试
2011-03-02 14:44 10741 各软件版本 Apache 2.2.4 因为jd_mod 用 ... -
Tomcat源码分析之JNDI
2011-03-02 14:43 1470在tomcat服务器中,我们可以通过配置文件%CATALINA ... -
tomcat和apache整合
2011-03-02 14:42 945为什么要整合了.其实很简单.原因就是: tomcat在静态 ... -
将Tomcat解压缩版变成服务形式运行,并修改Tomcat的启动内存参数
2011-03-02 14:41 1294许多朋友为了调试方便,下载使用的Tomcat是.zip的解压缩 ... -
Tomcat5.5.x配置整理 - 在重新启动Tomcat的webapp的时候,禁止把session写入文件
2011-03-02 14:39 949修改conf/web.xml 取消注释: <!--- ... -
java.lang.OutOfMemoryError: PermGen space及其解决方法
2011-03-02 14:38 7961、PermGen space的全称是Permanent Ge ... -
Tomcat 同时侦听多端口,多应用
2011-03-02 14:37 1028当你使用Tomcat作为Web Server的时候,是不是会想 ... -
Tomcat5.5.x配置整理 - 配置日志
2011-03-02 14:33 984在D:\jakarta-tomcat-5.5.8\comm ... -
Tomcat5.5.x配置整理 - 增强SessiionID的生成算法和长度
2011-03-02 14:32 887查看复制到剪切板打印 <Manage ... -
Tomcat5.5.x配置整理 - 发布webapp到网站根目录
2011-03-02 14:31 10771。直接复制到ROOT目录下。 2.因为无法创建无名字的xml ...
相关推荐
认识JVM内存优化, 避免最大的误区:认为JVM内存越大越好。看到一个线程 blocked就认为阻塞了。
Linux环境的Tomcat JVM内存优化 java虚拟机内存溢出问题的解决
淘宝林昊总结的JVM优化问题,比他写的那本书讲的更深入些
jvm优化;
Jvm性能优化-JVM内存结构原理分析03
JVM内存模型深度剖析与优化
JVM 深入学习教程深入分析JVM教程!jvm 内存原型,优化等等
某硅谷jvm内存分析优化教程,链接失效,请私聊我。某硅谷jvm内存分析优化教程,链接失效,请私聊我。某硅谷jvm内存分析优化教程,链接失效,请私聊我。
数据库简单优化、jvm内存数据库简单优化、jvm内存数据库简单优化、jvm内存数据库简单优化、jvm内存
JVM内存模型和性能优化
jvm性能调优-jvm内存模型和优化-performance-jvm-memorymodel-optimize
1、JVM参数推荐 2、Java运行时数据区 3、JVM内存模型 4、堆的内存划分 5、垃圾回收(GC) 6、JVM参数汇总
java虚拟机jvm及Tomcat中的jvm有关内存的设置与调优
Tomcat性能优化及JVM内存工作原理,适用于运维人员,开发人员
其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容; 其三是非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用; 本文...
23丨如何优化JVM内存分配?.html
NULL 博文链接:https://lihongchao87.iteye.com/blog/1688576
- 了解下我们为什么要学习JVM优化 - 掌握jvm的运行参数以及参数的设置 - 掌握jvm的内存模型(堆内存) - 掌握jamp命令的使用以及通过MAT工具进行分析 - 掌握定位分析内存溢出的方法 - 掌握jstack命令的使用 - 掌握...
JVM的内容分享,包含JVM的优化目标、优化原则、JVM组成、内存区域划分、垃圾回收算法、垃圾回收器、FullGC触发时机、对象布局、元空间存储、GC调优