Java 占用的内存远远超过使用 -Xmx 分配的内存

2022-09-01 11:55:21

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

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

这一切都可能是堆栈上的内存吗?,我很确定我永远不会超过大约300个方法调用深度(是的,这是一个递归DFS搜索),所以这必须意味着每个堆栈帧都消耗了近一兆字节,这似乎很难相信。

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

更新:我现在正在使用以下JVM选项,没有效果(根据顶部,仍然大约300m):-Xss104k -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。我尝试添加-可可,现在(使用所有其他选项)它只有59米。所以我想这解决了我的问题。谁能解释为什么这是必要的?另外,我应该知道有什么缺点吗?

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


答案 1

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

  • JVM 本身的基本内存开销
  • 堆空间(以 -Xmx 为界)
  • 永久生成空间(-XX:MaxPermSize - 不是所有JVM的标准)
  • 线程堆叠空间(每个堆栈 -Xss),根据线程数的不同,空间可能会显著增长
  • 本机分配使用的空间(使用 ByteBufer 类或 JNI)

答案 2
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]

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

下面的示例阐释了这种情况。我已经使用以下启动参数启动了我的tomcat:

-Xmx168m -Xms168m -XX:PermSize=32m -XX:MaxPermSize=32m -Xss1m