【问题标题】:What does fragmented memory look like?碎片化的记忆是什么样的?
【发布时间】:2026-02-20 21:55:01
【问题描述】:

我有一个移动应用程序随着时间的推移速度变慢。我的预感,(部分由this article 提供)是这是由于内存碎片减慢了应用程序的速度,但我不确定。这是应用程序的内存使用随时间变化的漂亮图表:

fraggle rock http://kupio.com/image-dump/fragmented.png

图表上的 4 个峰值是应用程序上完全相同任务的 4 次执行。我开始任务,它分配了一堆内存,它坐了一会儿(顶部的平线),然后我停止了任务。此时它调用 System.gc();并且内存被清理了。

可以看出,完全相同的任务的 4 次运行中的每一次都需要更长的时间来执行。图中的低点都返回到相同的水平,因此任务运行之间似乎没有任何内存泄漏。

我想知道的是,内存碎片是一个可行的解释,还是我应该先看看其他地方,记住我已经做了很多寻找?图上的低点相对较低,所以我的假设是在这种状态下内存不会很碎片化,因为不会有很多小的内存漏洞会导致问题。

我不知道 j2me 内存分配器是如何工作的,所以我真的不知道。任何人都可以建议吗?有没有其他人遇到过这个问题并识别出应用程序的内存配置文件?

【问题讨论】:

  • 普通 Java VM 压缩其堆作为其垃圾收集职责的一部分(删除任何碎片) - 虽然不确定 J2ME...

标签: java memory memory-management java-me memory-fragmentation


【解决方案1】:

如果您有一点时间,您可以通过使用内存池技术重新使用内存来测试您的理论:任务的每次运行都使用“相同”的内存块,方法是从池中获取它们并在发布时归还。

如果您在进行此调查后仍然看到性能下降,则不是内存碎片导致问题。让我们都知道您的结果,我们可以帮助您进一步排除故障。

【讨论】:

    【解决方案2】:

    内存碎片会导致它......不清楚的是应用程序使用内存是否导致分页?这也会减慢速度......并可能导致同样的问题。

    【讨论】:

      【解决方案3】:

      问题确实是内存碎片,您对此无能为力。

      但在您绝望地放弃之前,请尝试使用执行分析器运行您的应用程序,看看它是否在一个意想不到的地方花费大量时间执行。减速实际上可能是由于您的算法存在问题,与内存碎片无关。正如人们已经说过的,J2ME 垃圾收集器不应该受到碎片问题的困扰。

      【讨论】:

        【解决方案4】:

        考虑查看垃圾收集统计信息。如果你的理论成立,你应该在最后一次运行时比第一次运行更多。另一个想法可能是其他东西会占用您的内存,因此您的应用程序内存更少。

        换句话说,分析器时间:)

        【讨论】:

          【解决方案5】:

          你在什么操作系统上运行它?我有一些使用 Windows CE5(或 Windows Mobile)设备的经验。 CE5 的操作系统级别的内存架构已经非常糟糕,对于内存密集型应用程序来说很快就会失败。您的图表没有任何比例,但每个进程在 CE5 上仅获得 32MB 的地址空间。虚拟机和共享库也将分担它们的公平份额,而你所剩无几。 解决此问题的唯一方法是重新使用您分配的内存,而不是将其返回给收集器并稍后重新分配。当然,这比您通常希望在 Java 中进行的低级编程要多得多,但在这个平台上,您可能不走运。

          【讨论】: