Java最大内存参数似乎不起作用

时间:2015-12-17 21:24:12

标签: java jar

我有一个在服务器环境中按需运行的Jar文件,我想限制它使用的内存量,以便多个同时发送的实例可以轻松运行。但是,在设置-Xmx512M参数后,似乎Java仍在使用更多内存。我使用以下命令:

 java -Xmx512M -jar Reporter.jar /tmp/REPmKLs8K

但是我可以看到该过程使用的不仅仅是:

Resource:     Virtual Memory Size
Exceeded:     1657 > 400 (MB)
Executable:   /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/jre/bin/java
Command:      java -Xmx512M -jar Reporter.jar /tmp/REPmKLs8K

我不确定为什么会这样,并且它可能是内存报告软件(ConfigServer Firewall)的问题。有没有人经历过类似的事情?

3 个答案:

答案 0 :(得分:0)

-Xmx是最大堆大小,而不是进程大小。

请参阅:What does Java option -Xmx stand for?

答案 1 :(得分:0)

-Xmx用于指定最大堆分配,但java需要更多内存用于JVM,pergem空间(Java 7及以下版本)等...您可以看到这post for memory structure

您可以使用JVisualVM之类的工具来分析JVM中的实际内存使用情况。

答案 2 :(得分:0)

-Xmx无法控制您认为它控制的内容。

它只控制JVM堆,而不是JVM堆中的所有内容,并且堆占用了您为管理和簿记指定的更多本机内存。

您无法控制您想要控制的内容,-Xmx仅控制Java堆,它不控制JVM对本机内存的消耗,这种消耗完全不同基于实施。 JVM以完全不同的方式使用本机内存,它依赖于每个JVM实现及其运行的操作系统。

来自以下文章Thanks for the Memory ( Understanding How the JVM uses Native Memory on Windows and Linux )

维护堆和垃圾收集器使用您无法控制的本机内存。

  

需要更多的本机内存来维护状态   内存管理系统维护Java堆。数据结构   必须分配以跟踪免费存储并记录进度   收集垃圾。这些数据结构的确切大小和性质   随实施而变化,但许多与大小成正比   堆。

并且JIT编译器使用本机内存,就像javac

一样
  

字节码编译使用本机内存(与静态内存相同)   编译器如gcc需要内存运行),但两者都是输入(   字节码)和JIT的输出(可执行代码)也必须   存储在本机内存中。包含许多的Java应用程序   JIT编译的方法比较小的应用程序使用更多的本机内存。

然后你有使用本机内存的类加载器

  

Java应用程序由定义对象结构的类组成   和方法逻辑。它们还使用Java运行时类中的类   库(如java.lang.String)并可能使用第三方   库。只要这些类需要存储在内存中   他们正在被使用。如何存储类因实现而异。

我甚至不会开始引用关于线程的部分。

Plain and simple the JVM uses more memory than what is supplied in -Xms and -Xmx and the other command line parameters.

类加载器和应用程序可以有多个,占用大量内存,而这些内存很难记录。 JIT消耗内存,交易时间空间,这在大多数时间是一个很好的交易。

  

上面的一些链接可能指的是较旧的Java版本; Java 8以不同方式处理垃圾收集和内存分配,但上述一般规则适用。