如何(不)处理高内存使用?

How to (not) deal with high memory uses?

我是分析 java 应用程序的新手,当我看到我的小应用程序可能占用整个操作系统的两倍内存 800MB 和一些用户交互后大约 450MB 时,我不确定。

所以我已经阅读了一些关于内存分配和 gc 工作原理的文章,看起来 JVM 会尽其所能,而且大多数时候你的应用程序不需要那么多内存 运行 .

所以我测试了在不崩溃我的应用程序的情况下我可以限制多少堆并在 -Xmx32MB 停止测试。

除了应用程序使用的内存减少近 30 倍之外,没有明显的性能损失,我感到很惊讶。

所以现在我想知道...

(1) ...是否有任何限制堆的downsites?

(2) ...如果限制堆是常见的,或者是否建议让 JVW 决定它需要和想要使用多少内存?

(3) ...找出您的应用程序需要 运行 的最小内存大小的最佳方法是什么? (我只是感兴趣)

(4) ... 我应该在限制堆时遇到性能损失吗?

提前致谢!

非常简短地回答 1 和 4:是的。对 2 的非常简短的回答:否。

您的垃圾收集器将不得不做更多的工作,这对性能不利。第三个问题很有趣。 您 运行 正在嵌入或限制某些东西吗?它是一个巨大的多线程应用程序吗?您的应用程序是否需要超过可用的 RAM? 如果你对这些问题中的任何一个回答是 运行 探查器,而不是尝试不同的内存分配,试着看看你的代码在哪里吃掉了你的 ram?您是否在可以使用本机数据类型(例如 byte[])的地方使用奇特的对象(例如 List)?

1) 是的,您的可用内存较少,

2) 设置内存大小以适应程序是很常见的。

3) 找出最佳大小的最佳方法是使用实​​际工作负载测试您的程序。

4) 是的,有时有一点,有时很多。这取决于你在做什么。如果您需要节省内存,您可能会发现可接受的性能损失是值得的。

很可能您使用的 new 比您真正需要的要多得多。

如果是的话,也是在影响你的表现,因为new不便宜,就算你不算gc

有一种快速找出答案的方法。 取几个样本,如 this post。 如果您发现不止几个人在做 new,那是您的问题。

人们经常做的是将 new 放在一个循环中,而他们也可以将它放在外面。

一个相关的问题是他们可能会做很多 string + string + string,这会在下面做很多 new-ing,而他们也可以使用字符串生成器。