1

我们提供在 Linux、AIX 和 HP-Ux (PA-RISC) 上运行的 Java 应用程序。我们似乎很难从在其他两种环境中运行良好的应用程序中获得可接受的 HP-Ux 性能水平。执行时间和内存消耗都是如此。

虽然我还没有找到关于“为什么”的权威文章,但我认为使用“top”测量内存消耗是一种粗略的方法,因为共享代码会产生误导性结果。但是,对于 HP-Ux 上的内存消耗已成为问题的客户站点,这就是我们所要做的。这一次,当我们从 Java 1.4 迁移到 Java 1.5(在 HP-Ux 11.23 PA-RISC 上)时,它才成为一个问题。“问题”是指机器停止创建新进程,因为我们已经耗尽了所有 16GB 的物理内存。

通过测量“之前”和“之后”的总“可用内存”,我们试图衡量 Java 应用程序消耗了多少。我编写了一个快速应用程序,将 10,000 个随机 64 位字符串存储在 ArrayList 中,并尝试使用这种方法来测量 Java 1.4 和 Java 1.5 下 Linux 和 HP-Ux 上的消耗。

结果:

惠普 Java 1.4 ~60MB

惠普 Java 1.5 ~150MB

Linux Java 1.4 ~24MB

Linux Java 1.5 ~16MB

谁能解释为什么会出现这些结果?这是“顶部”测量空闲内存的方式的一些特质吗?HP 上的 Java 1.5 真的消耗的内存是 Java 1.4 的 2.5 倍吗?

谢谢。

4

4 回答 4

1

JVM 可能只是具有不同的默认参数。堆将增长到您配置允许它的大小。Sun VM 上的默认设置是机器内存的一定百分比——也就是说,默认情况下,如果您使用具有更多内存的机器,Java 将使用更多内存。

如果 HP-UX VM 没有对 HP 进行此类调整,我会感到非常惊讶。我建议你摆弄这两个参数 - 找出你可以使用的最小最大堆大小,而不会影响性能或吞吐量。

于 2008-10-30T04:23:22.617 回答
1

我现在没有 HP 盒子来检验我的假设。但是,如果我是你,我会使用像 JConsole(JDK 附带)或 yourkit 这样的分析器来衡量正在发生的事情。

但是,您似乎是在发现有问题后开始测量的;所以,我并不否认它正在发生——只是指出我在同样情况下会做的事情。

于 2008-10-30T02:55:12.403 回答
0

首先,不清楚您通过“10,000 个随机 64 位字符串”测试测量了什么。你应该启动应用程序,测量它的引导内存占用,然后运行你的测试。Java 1.5 很容易在启动后立即获得更多堆(例如,由于堆管理器设置)。

其次,我们确实在 HP-UX 下运行 1.4、1.5 和 1.6 下的 Java 应用程序,并且它们没有表现出任何特殊的内存要求。不过,我们有安腾硬件。

三、为什么要用top?为什么不直接打印 Runtime.getRuntime().totalMemory()?

第四,通过向 ArrayList 添加值,您会创建内存碎片。ArrayList 必须不时将其内部存储翻倍。根据 GC 设置和 ArrayList.ensureCapacity() 实现,未收集的内存量可能在 1.4 和 1.5 之间有很大差异。

本质上,您没有找出问题的原因,而是运行了一个随机测试,它没有给您任何有用的信息。您应该在应用程序上运行分析器以找出内存泄漏的位置。

于 2008-10-30T04:16:17.873 回答
0

您可能还想查看您正在尝试解决的问题......我不认为有很多问题会占用 16GB 内存,而这些问题不需要进行一轮好的优化。

您要启动多个虚拟机吗?您是否将大型数据集读入内存,并且没有足够快地丢弃它们?等等等等等等

于 2008-10-30T14:26:38.687 回答