最近三天两头遇到 java.lang.outofmemoryError 这个问题。所以记录一下
文章一
转自: <http://www.javaeye.com/topic/413647>
堆(Heap)和非堆(Non-heap)内存
按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。
堆内存分配
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、 -Xmx相等以避免在每次GC 后调整堆的大小。
非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
JVM内存限制(最大值)
首先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了
几个需要设置的jvm arg 的地方
1.tomcat/bin/catalina.bat 如果在启动tomcat的时候或者是在程序运行的时候报内存溢出。并且程序是在tomcat下运行的话。可以修改catalina.bat <操作系统式win>
JAVA_OPTS=%JAVA_OPTS% -Xms800M -Xmx800M -XX:MaxNewSize=512M -XX:PermSize=256M -XX:MaxPermSize=512M
2.如果在eclipse下使用外置的tomcat启动的时候报内存溢出如图所示:
当然也可以设置
XX:MaxNewSize=512M -XX:PermSize=256M -XX:MaxPermSize=512M;
3.当启动eclipse时报内存不够用时
可以再eclipse的目录下设置eclipse.ini .
当然也可以再eclipse的图标下的属性中设置。
文章二
转自: <http://www.javaeye.com/topic/119729>
java内存堆栈不够用时我们会寻求java参数-Xms和-Xmx的帮助,网上也有许多前辈给出了例子,但很多人喜欢把-Xms和-Xmx的值设置成一样的,甚至我还见过有吧-Xms设的比-Xmx还要大(-Xms是最小值,-Xmx是最大值)。
一开始我也不知道这两个值设成一样会有什么问题,但是我在作项目http://youmonitor.us/ 时发现,当我把-Xms和-Xmx设置成一样时,java会不断地吃内存。起先不知道怎么回事,经过测试后发现,原来java的垃圾回收器在内存使用达到-Xms值的时候才会开始回收,如果两个值一样,那就意味着,只有当java使用完所有内存时才会回收垃圾,这样一来内存当然不停的涨。希望我的教训对各位有所帮助。