如何永久增加Java堆内存?

28

我在Java堆内存方面遇到了一个问题。我开发了一个客户端服务器应用程序,它作为Windows服务运行,需要超过512MB的内存。我有2GB的RAM,但是当我运行我的应用程序时,它会抛出一个异常:

内存不足错误:Java堆空间

但是我已经在Java控制面板中设置了堆大小(最大512MB),但我仍然收到相同的错误。我无法通过命令行设置堆大小,因为我的应用程序作为Windows服务运行,那么我该如何增加默认的堆大小呢?


1
控制面板中的设置仅影响小程序和Java Web Start应用程序,因此不会对您的应用程序产生任何影响。 - assylias
你是如何将Java运行为Windows服务的?通常,无论您使用哪种实用程序执行此操作,您都可以指定命令行参数。 - Peter Lawrey
@Mr.Cool 你应该更改下面的被接受的答案。 - Grant Foster
5个回答

49
Java虚拟机需要两个命令行参数来设置初始堆大小和最大堆大小:-Xms和-Xmx。您可以添加一个名为_JAVA_OPTIONS的系统环境变量,在那里设置堆大小值。
例如,如果您想要512Mb的初始堆和1024Mb的最大堆大小,则可以使用以下命令:

在Windows下:

SET _JAVA_OPTIONS = -Xms512m -Xmx1024m

在Linux下:

export _JAVA_OPTIONS="-Xms512m -Xmx1024m"

可以通过使用 Runtime 类的 totalMemory() 方法在程序中读取默认的 JVM 堆大小。请使用以下代码来读取 JVM 堆大小。

public class GetHeapSize {
    public static void main(String[]args){

        //Get the jvm heap size.
        long heapSize = Runtime.getRuntime().totalMemory();

        //Print the jvm heap size.
        System.out.println("Heap Size = " + heapSize);
    }
}

5
在Linux系统中,使用命令"export _JAVA_OPTIONS=..."可以设定Java运行时的参数。为了验证这一设置是否生效,可以通过执行命令"java -version"来查看第一行的输出结果,如果显示类似于“Picked up _JAVA_OPTIONS: -Xms512m -Xmx2048m”这样的信息,则说明你已成功设定了Java运行时的选项。 - rickfoosusa
我不确定原因何在,但是对于我来说,Java虚拟机无法在多个堆选项(初始和最大)下启动。只有在“_JAVA_OPTIONS”中有一个选项时才能启动。 - Hack-R
_JAVA_OPTIONS 运行得非常好,而且也被 gradle 捕捉到了。 - ady

4
这是我的解决方法:

导出 _JAVA_OPTIONS="-Xmx1g"

注意不能有空格,因为我在尝试时没有成功。建议直接复制粘贴。然后运行命令:

java -XshowSettings:vm

输出结果会告诉你:

Picked up _JAVA_OPTIONS: -Xmx1g


3

如果您需要增加保留内存,请使用VM参数-Xms和-Xmx,例如使用-Xms512m -Xmx512m。还有一个参数-XX:MaxPermSize=256m,它可以更改永久代保留的内存大小。

如果您的应用程序作为Windows服务运行,在控制面板->管理工具->服务中,您可以为服务添加一些运行参数。


我可以像这样设置环境变量吗?"JAVA_OPT=-Xms512m -Xmx512m" - Mr.Cool
不确定这个,从未尝试过。如果您尝试了,请在此处发布结果;) 我已更新我的帖子,您可以向Windows服务添加一些参数。 - Jan Hruby
2
JAVA_OPTS环境变量通常是针对您正在运行的脚本(如tomcat启动脚本)特定的。您不能假设设置它会产生任何影响。请使用下面提到的_JAVA_OPTIONS。它适用于Windows和Linux,前提是您正在使用Oracle提供的JVM。不能保证在JRockit或IBM JVM上工作。 - Matt
1
@ Jan Hruby,我用另一种方式尝试了一下。我为我的应用程序编写了服务包装器,并在服务包装器配置中指定了最大和最小的Java堆大小,现在它运行得很好,感谢您宝贵的评论。 - Mr.Cool

1
您还可以使用以下内容扩展内存:
导出 _JAVA_OPTIONS="-Xms512m -Xmx1024m -Xss512m -XX:MaxPermSize=1024m"
Xmx指定Java虚拟机(JVM)的最大内存分配池
Xms指定初始内存分配池。
Xss设置线程堆栈的内存大小
XX:MaxPermSize:最大永久代大小

-6
请注意,在遇到 java.lang.OutOfMemoryError: Java heap space 后增加Java堆大小通常只是一个短期解决方案。
这意味着,即使您将默认的Java堆大小从512 MB增加到2048 MB,如果您正在处理内存泄漏,则在某些时候仍可能出现此错误。要问的主要问题是为什么首先会出现此OOM错误?这真的是Xmx值太低还是另一个问题的症状吗?
在开发Java应用程序时,始终重要的是及早了解其静态和动态内存占用量要求,这将有助于防止复杂的OOM问题。通过适当的应用程序分析和负载测试,可以实现JVM Xms和Xmx设置的正确调整。

32
您说的内容并没有错,但这不应该被接受作为答案,因为它根本没有回答提问者的问题。 - searchengine27
1
是的,这个“答案”完全忽略了用户希望定期运行需要大量内存数据的作业的可能性...与内存泄漏无关。 - Terrible Tadpole

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