【问题标题】:Is it normal for a java program to run at 60M or 90M?java程序跑60M还是90M正常吗?
【发布时间】:2012-01-15 18:50:20
【问题描述】:
我有一个代理服务器程序,它侦听套接字并创建一个线程池来处理连接,如果需要处理任何额外的开销,这些连接会产生新线程。当我在 java 1.5 上启动程序时,它的内存占用是 90M,而如果我使用 java 1.6 jvm,它有 60M 的占用,这对于一个简单的代理服务器程序来说似乎更大,是否正常?
我问这个是因为系统的内存相当有限,有时它会抛出 OutOfMemoryException。
以上统计数据是当我开始时初始线程池大小小于 10。我将初始线程池大小增加到 50,它在 jvm 1.5 上的内存占用约为 120M。
如何减少内存使用量?
【问题讨论】:
标签:
java
memory
memory-leaks
out-of-memory
【解决方案1】:
这似乎适合小型 Java 进程 - 请记住,如果您正在寻找非常小的内存占用,Java 并不是一个理想的选择。
您应该记住,JVM 是基于堆栈的机器,每个线程都有自己的堆栈。
堆栈的大小因您运行的 JVM 类型而异——(我相信,因为我从 oracle.com 丢失了详细说明这些值的页面)32 位 JVM 以 320kb 堆栈运行每个线程,而 64 位 JVM 为每个线程分配 1Mb - 这解释了为什么拥有大线程池会增加内存大小。
除了 Stack,JVM 还为 Heap 分配内存空间 - Stack 空间通常不是从 Heap 分配的,所以所有这些都会增加。
如果您超出了内存限制,您可以尝试通过在启动 Java 应用程序时使用命令行开关来限制使用量。
java -Xmx100m -Xss128k <followed by your other usual params>
-
-Xmx 用于限制最大堆大小(例如,-Xmx100m 会将堆限制为 100Mb。
-
-Xss 用于限制分配给每个线程的堆栈大小(例如,-Xmx128k 会将每个堆栈限制为 128Kb)。
您可以使用其他调整参数,但是在限制内存时应该小心,因为这可能会导致应用程序出现问题。
垃圾收集是另一个可以调整的领域,以帮助内存使用,但我不会在这么小的应用程序上进入那个领域。
正如 Ingo 所提到的,我建议您对应用程序使用分析器来查看内存分配的位置 - 许多流行的 IDE 要么内置了分析器,要么将它们作为插件提供。
【解决方案2】:
这是很常见的尺寸。显而易见的答案 - 使用 java 1.6 可以获得更低的内存占用。要确定您的内存去了哪里,您需要进行分析。
【解决方案3】:
听起来很正常。如果内存占用很重要,是否值得尝试不同的 JVM,因为它们可能更高效或臃肿。您可以尝试减少线程堆栈和 TLAB 分配大小以减少每个线程的开销。
【解决方案4】:
您应该使用一种工具来帮助您分析程序的内存需求。
例如,您可能想查看jvisualvm。
您可以实时查看内存分配情况或拍摄快照并逐个类别分析内存消耗。