30

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

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

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

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

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

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

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

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

4

5 回答 5

21

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

  • JVM本身的基本内存开销
  • 堆空间(以 -Xmx 为界)
  • 永久代空间(-XX:MaxPermSize - 并非所有 JVM 的标准)
  • 线程堆栈空间(每个堆栈的-Xss)可能会根据线程数显着增长
  • 本机分配使用的空间(使用 ByteBufer 类或 JNI)
于 2013-03-07T21:41:07.477 回答
9
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]

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

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

-Xmx168m -Xms168m -XX:PermSize=32m -XX:MaxPermSize=32m -Xss1m
于 2015-10-11T09:45:17.893 回答
6

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

-Xmx150m -Xss50m

例如。

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

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

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

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

于 2013-03-07T21:37:13.497 回答
4

重要的是要注意“使用的总内存”(Linux 领域的 RSS)包括 JDK 堆(+其他 JDK 区域)以及分配的任何“本机内存”。

例如,这些人发现在 GC 之间分配过多的 jaxbcontexts(具有关联的本机内存)可能会导致它使用大量额外的 RAM。如果您不关闭它(或 GZipStream 等),另一个常见的显然是 ZipInflater

http://sleeplessinslc.blogspot.com/2014/08/jvm-native-memory-leak.html

他的最终解决方法/修复是“更频繁地”进行 GC(通过使用 GC1 垃圾收集器,或指定较小的[讽刺地] -Xmx 设置)或通过缓存 JaxBContext 对象(因为它们没有关闭方法,因此您无法控制泄漏)。

另请注意,有时您可以通过检查 jstack 找到内存罪魁祸首:http: //javaeesupportpatterns.blogspot.com/2011/09/jaxbcontext-performance-problem-case.html

有时也可能“错过”关闭,例如 GZipStreams 意外http://kohsuke.org/2011/11/03/quiz-time-memory-leak-in-java

于 2015-01-07T21:34:53.783 回答
1

您是否尝试过使用 JVisualVM?

http://docs.oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html

我经常发现它可以帮助我追踪这些东西。它会向您显示每种内存的使用量,甚至让您深入了解并找出什么。

于 2013-03-07T21:46:07.763 回答