由于:java.lang.OutOfMemoryError: Java 堆空间,引起的问题。

5

我的目标:

我希望能够为1000名用户运行我的应用程序。

现在:

我正在尝试为100个用户运行此应用程序。 在应用程序运行期间,我想为每个用户执行一些处理,每个用户至少需要一个小时的时间,因此我为每个用户使用一个线程。

错误:

Caused by: java.lang.OutOfMemoryError: Java heap space

我已经尝试弄清楚这是什么意思,但我不确定如何解决它。

有人能帮我吗?


似乎你正在使用比你拥有的更多的内存。 - CloudyMarble
在我的情况下,我的RAM被100%使用,因为有太多的应用程序在运行。关闭一些应用程序后,错误消失了。 - Blasanka
5个回答

9
这个错误意味着您的程序需要比JVM允许使用的内存更多的内存!因此,您基本上有两个选择:
1.使用 -Xmx 选项(例如1024 MB: -Xmx1024m )增加默认允许程序使用的内存量。
2.修改您的程序,使其需要更少的内存,使用较小的数据结构并且在程序中不再使用的对象不用了就销毁。
正如Peter Lawrey所指出的那样,在这种情况下使用分析工具查看程序正在执行什么通常是一个好主意。

5

使用带有有限数量工作线程的生产者/消费者模式

100+个线程是荒谬的 - 难怪您的应用程序会崩溃。


2
我同意你的观点,但是我必须指出100多个线程并不那么荒谬。实际上,如果你检查运行Spring和Hibernate的Tomcat/jetty中的线程,可能已经有大约50-60个与框架相关的线程。想一想,在tomcat池默认配置的threadPool大小为200的情况下,100多个线程绝对不算荒谬。话虽如此,生产者/消费者模式与工作线程确实是适当的解决方案,除了使每个进程所需时间少于1小时并且需要更少的堆或增加maxHeapSize本身。 - Nikola Yovchev
1
@baba 抱歉,但是100多个线程每个都以100%的CPU运行至少1小时荒谬且没有生产力的。对于CPU密集型处理,您希望的线程数大致不超过CPU数量。在J2EE容器中,这么多线程实际上都处于休眠状态,并且只保留在那里以维护状态,以便当它们(偶尔)唤醒并开始工作时,它们可以立即响应。 - Bohemian
1
是的,同时运行100个线程超过1-2秒已经很疯狂了。我只是想指出,如果其中大部分线程处于睡眠状态,就像我上面描述的框架一样,100多个线程并不是问题。 - Nikola Yovchev

2

您并没有提供任何信息表明这个问题与Stack Overflow给出的所有答案非常不同;

  • 您使用的内存过多,需要使用内存分析器来减少内存占用。
  • 您设置的最大内存太低了,需要使用-mx-Xmx增加最大内存。

我怀疑如果您希望1000个用户运行每个进程需要一个小时,您可能需要比您拥有的资源更多的资源,例如1000个核心? 我建议您根据CPU、内存、磁盘IO和网络IO所需求的水平来查看您需要多少硬件才能使用户以可接受的水平运行,例如20个用户,然后将其乘以50。


1

当您启动应用程序时,可以尝试增加JVM堆空间。您可以使用-Xmx2g将其设置为2GB。如果您正在运行32位Java,则我认为2GB是最高限度,但如果您有64位JVM,则应该能够更高。

编辑:

示例:java -Xmx2g MyApp


1

当出现内存错误时,我会检查两个方面:

  1. 分配给JVM的内存是否足够,如果不够,可以使用-Xmx来增加它。
  2. 彻底检查代码,90%以上的情况下,我发现错误是由于某些循环在某些边界条件下变成了递归。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接