2

我一直在编写一个要部署在浏览器中的 Java swing 小程序(对于小程序来说,ios 是很正常的,当然)。它使用 Java 2D

无论如何,我有一个用于开发目的的测试工具,它作为桌面应用程序运行。

基于完全相同的测试数据,Test Harness 版本的堆总大小为 18 Meg;这是基于在 Java 2D 画布上绘制大约 7000 个对象,大概有 30,000 个坐标对,加上其他零碎,因此 18 Meg 堆很大,但几乎可以理解。应用程序总大小为 40 兆。

现在我通过 IBM Websphere 运行与 Applet 完全相同的代码。

插件的内存增量上升到大约 160Meg!不知何故,相同的 java 代码正在设法使用 10 倍的内存。

我的老 CBM64 程序员对第一个数字并没有特别印象 - 它是一个数量级的 IMO 臃肿,但第二个是惊人的 - 有人知道什么可能会使用这么多内存吗?我正在使用 VisualVM,它有助于将 Object、char[] 和 String 之类的东西作为内存猪,我的课程都没有接近。

有趣的是,Float 和 Double 似乎占用了完全相同的内存量(每个 16 字节)。

我现在的主要猜测是使用 SOAP 进行数据检索导致内存使用量激增,并且由于未知的原因,SOAP XML 被保留而不是 GC'd。

还有其他人知道这里发生了什么吗?

4

2 回答 2

1

找到它 - 或其中一点。

当您使用 Axis 1.3 进行 SOAP 调用(首先获取数据)时,它不会释放 SOAP XML,直到下一次调用。

不幸的是,在这种情况下,只有一个初始数据填充调用,因此 Axis 一直挂在大约 150Meg 的 XML 上。足够简单的解决方法,进行第二次“空”调用以清除它。GC 后一切正常。

于 2012-10-05T10:41:36.997 回答
0

JVM 总是分配一个大于它需要或实际上可能在任何给定时间使用的内存池。任何对 JVM 内存使用的外部测量都可能具有误导性。

JVM 这样做有几个相当合理的原因:

  • 当垃圾收集器有更多空间来分配/移动对象时,它可以使垃圾收集器更有效地运行
  • 即使 GC 清除了一些空间,在假设程序可能再次需要它的情况下保留空间是有意义的
  • GC 通过懒惰地收集垃圾来避免不必要的工作——除非 GC 被迫执行收集,否则旧对象可以在堆上存在相当长的一段时间。这些物体没有造成任何伤害——如果需要,以后可以回收空间。

你可能只是看到了这种行为的结果。除非您确实遇到问题(例如 OutOfMemoryError - 这可能表明您有内存泄漏),否则不要担心。

ps Float和Double对象都占用16个字节的原因很可能是a)它们有一个对象头,b)然后填充它们以确保缓存行/内存寻址对齐。如果你在一个数组中包含很多浮点数/双精度数,那么你会发现它们分别占用 4 和 8 个字节。

于 2012-10-05T08:55:23.200 回答