查看/解决Windows XP内存碎片的工具
我们有一个Java程序,它需要大量的堆空间,我们从-Xmx1500m参数(以及其他命令行参数)开始,它指定最大堆空间为1500 MB。在刚重新启动的Windows XP机器上启动该程序时,它将启动并运行而不会出现问题。但是,如果该程序已经运行了几次,则计算机已经启动了一段时间等等,当它尝试启动时,我得到了这个错误:
Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
我怀疑Windows本身正遭受内存碎片的困扰,但我不知道如何确认这种怀疑。发生这种情况时,任务管理器和sysinternals procexp报告2000MB可用内存。我看了这个与内部分裂有关的问题
因此,第一个问题是,如何确认我的怀疑?
第二个问题是,如果我的猜想是正确的,有人知道有什么工具可以解决这个问题吗?我已经环顾了很多时间,但是除了定期重新启动计算机之外,没有找到任何有用的方法。
ps更改操作系统目前也不可行。
解决方案
对该应用程序使用Minimem(http://minimem.kerkia.net/)可能会解决问题。但是,我不确定这是我们要寻找的答案。希望对我们有所帮助。
也许我们应该考虑启动程序并保留内存,而不是
每次运行后结束VM。寻找不同的GC选项并释放对象。
除非页面文件空间不足,否则问题不是计算机内存不足。虚拟内存的全部目的是允许进程使用比物理上可用的虚拟内存更多的虚拟内存。
不知道JVM如何处理堆,很难确切说明问题是什么,但是一个常见的问题是进程中没有足够的连续可用地址空间来允许扩展堆。为什么在机器运行了一段时间后这会是一个问题,这有点令人困惑。
我一直在研究类似的问题。我发现使用WinDBG以及使用"!address"和"!address -summary"命令运行程序对于跟踪进程的虚拟地址空间变得零散的原因非常有用。我们也可以尝试在重新启动后运行该程序,并使用"!address"命令拍摄地址空间的图片,然后在该程序不再运行时执行相同的操作。这可能会提示我们问题所在。可能很简单,因为额外的DLL正在加载可能会导致问题。
与Torlack达成共识,这在很大程度上是因为其他DLL正在加载并进入某些位置,从而使我们可以为VM大量获得的内存量大为减少。
如果我们有3G以上的内存可以移动Windows的某些内容,则可以在WinXP上做一些工作,在此处查找PAE:
http://www.microsoft.com/whdc/system/platform/server/PAE/PAEdrv.mspx
如果Java应用程序确实需要超过1.2G的内存,那么最好的选择是查看64位Windows,Linux或者OSX。如果我们在应用程序中使用任何种类的本机库,则必须将其重新编译为64位,但是与尝试重新构建dll和内容以最大程度地利用32位Windows上的内存相比,它要容易得多。 。
另一个选择是将程序拆分为多个VM,并使它们通过RMI或者消息传递或者其他方式相互通信。这样,每个VM可以拥有所需内存的某些子集。尽管不知道应用程序做什么,但我不确定这是否有任何帮助,尽管...
我怀疑问题是Windows内存碎片。在StackOverflow上还有一个问题,称为Windows XP上的Java Maximum Memory,它提到使用Process Explorer查看DLL映射到内存的位置,然后通过重新定位DLL来解决此问题,以便以更紧凑的方式加载到内存中。