`
superich2008
  • 浏览: 323052 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

基于java的程序OutOfMemory问题的解决及Xms/Xmx/Xss的解释和应用

阅读更多

长期以来一直都是做java应用的开发,所使用的开发工具基本上也都是基于java的,经常用的有eclipse, netbeans, ant, maven, cruisecontrol, tomcat, findbugs等。在使用这些工具的时候,有时候会碰到OutOfMemory的问题。

问题
--------------------------------------------------------------------------------

一般在遇到这个问题的时候,我们的第一印象是:一定是机器的内存不够用了。

可是通过进程管理器查看,物理内存都还有好多空余呢,根本就没有被占满。

那这又是什么原因呢?

直接原因是:在启动某个基于java的程序时,同时会设置一些参数以限制这个程序对内存的使用(如果不人工设置的话,也会有默认的设置),那么 java虚拟机在启动并运行这个程序的时候,就会按照设定的内存大小来运行,而当程序运行时需要更大内存的话,就可能会抛出异常。比如说,启动时我设置某 程序最大使用100M内存,那么,当这个程序需要使用100M以上内存时,就会抛出OutOfMemory的异常。

具体解释
--------------------------------------------------------------------------------

具体如下,在使用命令java和javaw时,命令行格式如下,其中"argument"部分就可以设置一些参数。
java [ options ] class [ argument ... ]
java [ options ] -jar file.jar [ argument ... ]
javaw [ options ] class [ argument ... ]
javaw [ options ] -jar file.jar [ argument ... ]

这里,跟内存使用相关的参数主要有三个:Xmx, Xms,Xss。

参考资料2中提供了这三个参数的相关说明。


-Xmsn
Specify the initial size, in bytes, of the memory allocation pool. This value must be a multiple of 1024 greater than 1MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is chosen at runtime based on system configuration. For more information, see HotSpot Ergonomics
Examples:
-Xms6291456
-Xms6144k
-Xms6m

-Xmxn
Specify the maximum size, in bytes, of the memory allocation pool. This value must a multiple of 1024 greater than 2MB. Append the letter k or K to indicate kilobytes, or m or M to indicate megabytes. The default value is chosen at runtime based on system configuration. For more information, see HotSpot Ergonomics
Examples:
-Xmx83886080
-Xmx81920k
-Xmx80m

-Xssn
Set thread stack size.
简单的总结一下。

Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢。

Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。

Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。

以上三个参数的设置都是默认以Byte为单位的,也可以在数字后面添加[k/K]或者[m/M]来表示KB或者MB。而且,超过机器本身的内存大小也是不可以的,否则就等着机器变慢而不是程序变慢了。

因此,对于一般的java应用程序来讲,我们只要把前两个参数设置合适基本上就可以了。第三个参数还是需要有很强的

各应用程序的设置方法
--------------------------------------------------------------------------------

1. 自开发的应用程序

我们启动时是以命令行方式启动,那么在命令行中加入Xms和Xmx即可。

Sample: java -jar test.jar -Xms32m -Xmx512m

2. eclipse

用文本编辑软件打开eclipse根目录下的eclipse.ini文件,修改里面的Xms和Xmx的值。

3. maven

有两种方法。

1). 用文本编辑软件打开%MAVEN_HOME%\bin下的mvn.bat文件(unix/linux为mvn),里面有一行设置MAVEN_OPTS的注释行,在maven 2.0.5中内容如下:

@REM set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000

我们只要在这行下面添加下面的一行即可。

set MAVEN-OPTS=-Xms32m -Xmx512m

2). 因为我们是使用命令行来调用maven的,所以可以在调用mvn之前,先执行上面那一行,这也是可以的。

4. ant, findbugs, cruisecontrol等程序的设置方法和maven是类似的。

ant有ANT_OPTS, findbugs有jvmargs, cruisecontrol有CC_OPTS。

5. 有些程序是在别的GUI程序中启动的,比如说在eclipse中启动web服务器(tomcat等)。类似于这样的启动方式,我们一般可以在宿主程序(本例中为eclipse)中的某个设置画面上找到关于启动参数的设置的。

参考资料
--------------------------------------------------------------------------------

1.http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html
2.http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html
3.http://java.sun.com/javase/6/docs/technotes/guides/vm/gc-ergonomics.html
4. JVM调优总结 -Xms -Xmx -Xmn -Xss

出处:http://blog.csdn.net/superbeck/archive/2009/11/11/4799407.aspx

**********************************************************************

以下是从网上找到的关于堆空间溢出的错误解决办法:

java.lang.OutOfMemoryError: Java heap space
===================================================

使用Java程序从数据库中查询大量的数据时出现异常:
java.lang.OutOfMemoryError: Java heap space


在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。

JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.

JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。
例如:java -jar -Xmn16m -Xms64m -Xmx128m MyApp.jar

如果Heap Size设置偏小,除了这些异常信息外,还会发现程序的响应速度变慢了。GC占用了更多的时间,而应用分配到的执行时间较少。

Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
Heap size的 -Xms -Xmn 设置不要超出物理内存的大小。否则会提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。

==========================================================
经过一个晚上的努力终于完成了一个文件替换指定字符串的程序,但是由于我要替换的全站程序html文件太多,所以eclipse下边老是在一个目录结束后报出java.lang.OutOfMemoryError: Java heap space的异常,然后就崩溃了。

我一想肯定是频繁操作造成来不及回收,于是在每个循环之后加上一个Thread.sleep(1000),发现还是到那个目录下就死掉,于是把 1000改成5000,还是到那里死掉,我想可能不是来不及回收这么简单,或许sun 的JVM里边刚好对于这种情况不释放也有可能。
接着我又把启动的参数添上一个 -Xmx256M,这回就可以了。

想一想,还是对于垃圾回收的原理不太了解,就在网上查了一下,发现了几篇不错的文章。

http://java.ccidnet.com/art/3539/20060314/476073_1.html
http://www.pconline.com.cn/pcedu/empolder/gj/java/0509/701281.html


还有:Java堆的管理—垃圾回收提到一下几点,很不错,或许可以作为写程序时候的准则:

  (1)不要试图去假定垃圾收集发生的时间,这一切都是未知的。比如,方法中的一个临时对象在方法调用完毕后就变成了无用对象,这个时候它的内存就可以被释放。

  (2)Java中提供了一些和垃圾收集打交道的类,而且提供了一种强行执行垃圾收集的方法--调用System.gc(),但这同样是个不确定 的方法。Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。

  (3)挑选适合自己的垃圾收集器。一般来说,如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收 集器,比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置,有比较多的闲置资源,可以考虑使用并行标记/清除收集器。

  (4)关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的,不要让自己的一个小错误导致内存出现大漏洞。

  (5)尽早释放无用对象的引用。
大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null,暗示垃圾收集器来收集该对象,还必须注意该引用的对象是否被监听,如果有,则要去掉监听器,然后再赋空值。

就是说,对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。

================================================
tomcat


遇到TOMCAT出错:java.lang.OutOfMemoryError: Java heap space,于是查了资料,找到了解决方法:
If Java runs out of memory, the following error occurs:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Java heap size can be increased as follows:

java -Xms<initial heap size> -Xmx<maximum heap size>
Defaults are:
java -Xms32m -Xmx128m

如果你用win
/tomcat/bin/catalina.bat 加上下面的命令:
set JAVA_OPTS=-Xms32m -Xmx256m

如果你用unix/linux
/tomcat/bin/catalina.sh 加上下面的命令:
JAVA_OPTS="-Xms32m -Xmx256m"


=========================================
原因:


使用Java程序从数据库中查询大量的数据时出现异常:
java.lang.OutOfMemoryError: Java heap space
在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。
JVM 堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。
解决办法:
tomcat_home/bin下catalina.bat(win)或catalina.sh(linux)执行代码前加上:
set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m

=============================================================
eclipse java.lang.OutOfMemoryError: Java heap space 解决方案
===========================================================
eclipse java.lang.OutOfMemoryError: Java heap space 解决方案

eclipse 有启动参数里设置jvm大小,因为eclipse运行时自己也需要jvm,所以eclipse.ini里设置的jvm大小不是具体某个程序运行时所用jvm的大小,这和具体程序运行的jvm大小无关。

那么怎么才能设置某个程序的jvm大小呢(当然控制台运行的话不会存在这个问题,如:java -Xms256m -Xmx1024m classname,这样就可以把当前程序的jvm大小给设定)?

因为eclipse里默认的一个程序的jvm配置为:-Xms8m -Xmx128m,所以我们的处理耗内存比较大时需要手动调整一下,以便不会内存溢出。具体的设置方法为:

选中被运行的类,点击菜单‘Run as ->Open Run Dialog...’,选择(x)=Argument标签页下的vm arguments框里输入 -Xmx512m, 保存运行就ok了

=======================================================
Eclipse中java.lang.OutOfMemoryError: Java heap space

错误2007-06-12 11:53java.lang.OutOfMemoryError: Java heap space错误

在tomcat in的catalina.bat里加
set JAVA_OPTS=-Xms256m -Xmx512m -Djava.awt.headless=true
256和512分别是MIN和MAX内存
在eclipse中的
windows->preferences..->tomcat->jvm..->jvm那一个文本框里,添加-Xms256m -Xmx512m
这样就可以了!

==================================
Eclipse中VM设定方法 - [] - Tag:java.lang.OutOfMemoryError: Java heap space

点击右键,选择run...,弹出窗口如下图,在vm输入框中填写合适的内存值即可。

==================================
eclipse中,黄线是警示。
private Log log = LogFactory.getLog(AddCateAction.class);//小黄线在log上。
这里的黄线是指你定义了私有变量log,但没有用到这个变量。
v.add(o); //这时eclipse下面出现了一个小黄线,表示仍然被引用?
这里是指add方法是不推荐的方法。

OutOfMemoryError和怀疑的引用没有关系,可能是循环创建对象导致java内存不足。

用参数指定java虚拟机的内存.
java -Xms256m -Xmx1024m -XX:MaxPermSize=256M

========================================================
2、如果在启动过程中出现内存溢出问题,抛出类似如下异常信息:
java.lang.OutOfMemoryError: Java heap space

可以尝试办法:
A.修改Tomcat\bin\catalina.bat,添加如下内容
set JAVA_OPTS=-Xms256m -Xmx512m -Djava.awt.headless=true [-XX:MaxPermSize=128M]

B.eclipse->windows->preferences..->tomcat->jvm..->jvm文本框里,添加-Xms256m -Xmx512m

C.eclipse->preference->java->instal jres->edit,增加参数:-Xms256m -Xmx512m

参考原因:JVM中如果98%的时间是用于GC且可用的, Heap size不足2%的时候将抛出此异常信息。
JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。
可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
Heap size的 -Xms -Xmn 设置不要超出物理内存的大小。否则会提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。

==================================================================

我的问题原因:

使用Spring+Hibernate从数据库中读取大量数据,使用了单例模式的AppContext的getBean,内存中缓存了大量的Entity Bean……

目前仍没有有效解决办法,通过加大JVM内存大小,以及修改数据读取方式(如:只读取有用信息)缓解了一下。

修改数据读取方式:
例如一个EntityBean有如下字段:id, name, age, address, description。如果程序中只用到了此Bean的id和name字段,那么从数据库中只用读此两字段,而不是读取整个bean以及关联的Bean。


出处:http://blog.csdn.net/jxzxm1_2/archive/2008/05/31/2499751.aspx

***************************************************************************

Increase heap size in Java to prevent java.lang.OutOfMemoryError

If Java runs out of memory, the following error occurs:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

This can have two reasons:

  • Your Java application has a memory leak. There are tools likeYourKit Java Profiler that help you to identify such leaks.
  • Your Java application really needs a lot of memory (more than 128 MB by default!). In this case the Java heap size can be increased using the following runtime parameters:
java -Xms<initial heap size> -Xmx<maximum heap size>

Defaults are:

java -Xms32m -Xmx128m

You can set this either in the Java Control Panel or on the command line, depending on the environment you run your application.

分享到:
评论

相关推荐

    实战java虚拟机

    通过深入学习JVM,我们可以优化程序性能、解决内存泄漏问题,以及更好地理解和调试Java应用。 首先,我们要了解JVM的基本结构。JVM主要包括类装载器、运行时数据区、执行引擎、本地方法接口和本地方法库。类装载器...

    内存不足OOM java.lang.OutOfMemoryError.

    Java中的“内存不足OOM (Out Of Memory):java.lang.OutOfMemoryError”是一个常见的运行时错误,它表示Java虚拟机(JVM)在尝试分配新的对象或数据结构时,发现系统内存不足以完成此操作。这个问题通常发生在程序...

    蚂蚁课堂-JVM快速入门2

    在Java程序运行过程中,最常见的两类内存溢出问题是堆内存溢出(Out of Memory: Heap Space)和 PermGen/Metaspace 溢出。堆内存溢出通常由于对象创建过多,导致堆空间不足以容纳所有对象。解决方法包括增大堆内存、...

    找到该死的OutOfMemoryError.docx

    在命令行启动Java应用时,可以设置`JAVA_OPTS`环境变量来调整内存参数,如`-Xms`用于设置初始堆大小,`-Xmx`用于设置最大堆大小,`-XX:PermSize`和`-XX:MaxPermSize`分别设定永久代的初始和最大大小,`-Xss`设定每个...

    JVM 18道面试题和答案.docx

    Java虚拟机(JVM)是Java程序的核心组成部分,它负责执行字节码并管理程序的内存。以下是对JVM内存模型、内存溢出和线程栈的详细解释: ...理解这些JVM概念对于解决性能问题和优化Java应用程序至关重要。

    内存溢出解决

    当程序运行时分配给它的内存空间不足以支撑其正常运行时,就会出现“内存溢出”(Out of Memory Error,简称OOM)。这通常发生在堆内存或方法区等内存区域耗尽时。对于Java应用而言,了解如何有效识别并解决内存溢出...

    eclipse下的tomcat内存设置大小

    解决这个问题,除了增加总的内存分配,还可以考虑对每个应用单独配置内存,或者优化应用程序的内存使用,减少内存泄漏。 总的来说,理解和配置Eclipse中的Tomcat内存设置是Java Web开发中的关键技能,能够有效避免...

    jboss配置内存大小[定义].pdf

    本文以“JBoss配置内存大小”为主题,详细解释了如何优化JBoss服务器运行时的内存分配,以避免因内存不足导致的性能问题或`Out of Memory`异常。 首先,Java虚拟机在启动时会根据特定的参数来设定内存分配。有两个...

    java OOM内存泄漏原因及解决方法

    Java OOM(Out Of Memory)是指Java虚拟机(JVM)因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时抛出的错误。出现OOM的原因主要有两点:一是分配的少了,即虚拟机本身可使用的内存太少;...

    jvm -spark-优化

    - **Heap OutOfMemory**:当堆内存不足时,JVM无法为新对象分配空间,此时会抛出`OutOfMemoryError`。通过增加`-Xmx`值或优化代码减少内存占用可以解决该问题。 - **Stack OutOfMemory**:当单个线程的栈空间耗尽...

    java是去蜗牛还是源码时代-JVM-:JVM-

    如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。 Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。 以上三个...

    JVM调优相关内容教程吐血整理干货.md

    - **-XX:+HeapDumpOnOutOfMemoryError**:当程序发生OOM(Out Of Memory)时,触发生成堆转储文件,方便后续分析。 - **-XX:HeapDumpPath=?**:指定堆转储文件的保存位置。结合`-XX:+HeapDumpOnOutOfMemoryError`...

    JVM优化与OOM分析PPT

    通过合理的配置JVM参数,可以显著提高应用程序的性能,解决诸如OOM等问题。本文档通过具体的案例分析,介绍了JVM的基本概念、工作原理以及调优技巧,希望能够帮助开发者更好地理解和掌握JVM调优的相关知识。

    JVM虚拟机面试题汇总

    4. **内存溢出(Out Of Memory Error, OOM)**: - **堆溢出**:对象实例数量超过最大堆容量限制。 - **虚拟机栈和本地方法栈溢出**:线程请求的栈深度大于虚拟机所允许的最大深度,或虚拟机在扩展栈时无法申请到...

Global site tag (gtag.js) - Google Analytics