当前位置: 首页 > 知识库问答 >
问题:

Java 使用比-Xmx分配的内存多得多的内存

束福
2023-03-14

我有一个项目(用 Java)为一个类编写,教授说我们不允许使用超过 200m 我使用 -Xmx50m 将堆栈内存限制为 50m(只是为了绝对确定),但根据顶部,它仍在使用 300m

我尝试运行Eclipse Memory Analyzer,它只报告26m

这些都是堆栈上的内存吗?我很确定我从来没有深入到超过300个方法调用(是的,这是一个递归DFS搜索),所以这意味着每个堆栈帧几乎要用掉1兆字节,这似乎很难相信。

该程序是单线程的。有人知道我可以减少内存使用的其他地方吗?此外,如何检查/限制堆栈使用的内存量?

更新:我现在使用了以下JVM选项,但没有效果(根据顶部,仍有大约300米):-Xs104k-Xms40m-Xmx40m-XX:MaxPermSize=1k

另一个更新:事实上,如果我让它运行更长一点(使用所有这些选项),大约一半的时间,它在4或5秒后突然下降到150米(另一半没有下降)。真正奇怪的是,我的程序没有随机性(正如我所说,它是单线程的),因此没有理由在不同的运行中表现不同

这可能与我正在使用的JVM有关吗?

java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~10.04)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

根据java-h,默认JVM是-server。我试着添加可可,现在(加上所有其他选项)只有590m。所以我想这解决了我的问题。有人能解释为什么这是必要的吗?还有,我应该知道哪些缺点吗?

还有一个更新:与服务器相比,可可真的很慢。这是一个糟糕的选择

共有3个答案

郗唯
2023-03-14

使用-Xmx您正在配置堆大小。要配置堆栈大小,请使用-Xss参数。这两个参数的总和应该大约是您想要的:

-Xmx150m -Xss50m

比如说。

此外,还有-XX: MaxPermSize参数来控制。-client的此参数默认值为32mb,-server64mb。根据您的配置也计算它。PermGen空间为:

永久生成用于保存VM本身的反射,例如类对象和方法对象。

所以基本上它存储JVM的内部数据,如类定义和实习字符串。

最后,我必须指出,有一部分是您无法控制的,那就是本机java进程使用的内存。Java是程序,就像其他任何程序一样,所以它也使用内存。如果您在任务管理器中查看内存使用情况,您将看到该内存以及程序内存消耗情况。

喻增
2023-03-14
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]

这里最大堆内存为 -Xmx,最小堆内存为 -Xms,堆栈内存为 -Xss 和 -XX maxPermSize

以下示例说明了这种情况。我用以下启动参数启动了tomcat:

-Xmx168m -Xms168m -XX:PermSize=32m -XX:MaxPermSize=32m -Xss1m
夹谷茂
2023-03-14

top命令反映了 Java 应用程序使用的内存总量。这包括:

  • JVM本身的基本内存开销
  • 堆空间(以-Xmx为界)
  • 永久生成空间(-XX: MaxPermSize-不是所有JVM的标准)
  • 线程堆栈空间(每个堆栈-Xss)可能会根据线程数显着增长
  • 本机分配使用的空间(使用ByteBufer类或JNI)
 类似资料:
  • 问题内容: 使用以下Java选项启动Apache Tomcat(Atlassian Confluence)实例: 但是,我看到启动后,它很快就耗尽了虚拟服务器上可用的1GB内存中的大部分。 总消耗的内存(堆+ PermGen)是否不应该保持在使用- Xmx指定的值以下?这引起的问题之一是我无法使用关闭脚本关闭服务器,因为它试图生成具有256MB内存的JVM,该JVM因不可用而失败。 问题答案: T

  • 我有一个非常简单的Web服务器类(基于JavaSE的类)。 当我使用此命令启动编译后的类以限制内存使用时:

  • 我的java应用程序工作了大约1天,(我使用不同的库来处理照片,比如ffmpeg、javacv、javacpp),然后我看到我的应用程序使用了9,5GB的RAM。 I set-XMX6G 在VisualVM中,我看到堆空间大小为188M visualVM中的堆空间 编辑: 是的,我的应用程序有时会出现异常Java.lang.outofmemoryerror:Java堆空间

  • 我有这些jvm参数集

  • 问题内容: 我们正试图在我们的Web应用程序中找到导致大量内存泄漏的元凶。我们在发现内存泄漏方面经验有限,但是我们发现了如何使用Eclipse MAT进行Java堆转储并对其进行分析。 但是,对于我们使用56 / 60GB内存的应用程序,堆转储的大小仅为16GB,而在Eclipse MAT中则更少。 语境 我们的服务器将Ubuntu 14.04上的Wildfly 8.2.0用于我们的Java应用程

  • 我们正试图找到web应用程序中大内存泄漏的罪魁祸首。我们在查找内存泄漏方面的经验相当有限,但我们了解了如何使用创建java堆转储,并在Eclipse mat中对其进行分析。 但是,由于我们的应用程序使用56/60GB内存,堆转储的大小只有16GB,在Eclipse mat中就更少了。 对于我们的java应用程序,我们的服务器使用Ubuntu14.04上的Wildfly8.2.0,其进程使用了95%

  • 我有一个jar文件,我使用单元文件运行。单元文件中的run命令如下: ExecStart=/usr/bin/java-Xms200m-Xmx465m——启用预览-jar-myapp-1.0.0.jar 我的应用程序总是记录允许使用的最大内存量。它使用以下代码对此进行记录: 由于某种原因, 的值总是比 参数的值小 左右。因此,如果jar文件使用参数运行,则应用程序将仅获得的可用RAM内存。 我的问题

  • 问题内容: 我在Linux下运行的Java应用程序有问题。 当启动应用程序时,使用默认的最大堆大小(64 MB),我看到使用tops应用程序为该应用程序分配了240 MB的虚拟内存。这会给计算机上的某些其他软件带来一些问题,这是相对有限的资源。 据我了解,保留的虚拟内存无论如何都不会使用,因为一旦达到堆限制,OutOfMemoryError就会抛出。我在Windows下运行了相同的应用程序,并且看