Java 使用的内存远多于使用 -Xmx 分配的内存

2022-01-22 00:00:00 memory memory-management stack java

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

I have a project I'm writing (in Java) for a class where the prof says we're not allowed to use more than 200m I limit the stack memory to 50m (just to be absolutely sure) with -Xmx50m but according to top, it's still using 300m

我尝试运行 Eclipse 内存分析器,它只报告 26m

I tried running Eclipse Memory Analyzer and it reports only 26m

这可能都是堆栈上的内存吗?我很确定我永远不会超过大约 300 个方法调用深度(是的,这是一个递归 DFS 搜索),所以这意味着每个堆栈帧都在使用几乎是一兆字节,这似乎令人难以置信.

Could this all be memory on the stack?, I'm pretty sure I never go further than about 300 method calls deep (yes, it is a recursive DFS search), so that would have to mean every stack frame is using up almost a megabyte which seems hard to believe.

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

The program is single-threaded. Does anyone know any other places in which I might reduce memory usage? Also, how can I check/limit how much memory the stack is using?

更新:我现在使用以下 JVM 选项没有任何效果(根据顶部仍然大约 300m):-Xss104k -Xms40m -Xmx40m -XX:MaxPermSize=1k

UPDATE: I'm using the following JVM options now with no effect (still about 300m according to top): -Xss104k -Xms40m -Xmx40m -XX:MaxPermSize=1k

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

Another UPDATE: Actually, if I let it run a little bit longer (with all these options) about half the time it suddenly drops to 150m after 4 or 5 seconds (the other half it doesn't drop). What makes this really strange is that my program has no stochastic (and as I said it's single-threaded) so there's no reason it should behave differently on different runs

会不会和我使用的 JVM 有关?

Could it have something to do with the JVM I'm using?

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.我尝试添加 -cacao,现在(使用所有其他选项)它只有 59m.所以我想这可以解决我的问题.谁能解释为什么这是必要的?另外,有什么我应该知道的缺点吗?

According to java -h, the default JVM is -server. I tried adding -cacao and now (with all the other options) it's only 59m. So I suppose this solves my problem. Can anyone explain why this was necessary? Also, are there any drawbacks I should know about?

另一个更新:cacao 与服务器相比真的很慢.这是一个糟糕的选择

One more update: cacao is really really slow compared to server. This is an awful option

推荐答案

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

Top command reflects the total amount of memory used by the Java application. This includes among other things:

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

相关文章