RAM内存重新分配 - Windows和Linux

时间:2009-11-15 19:28:11

标签: java .net memory-management

我正在研究一个涉及优化系统内能耗的项目。该项目的一部分在于根据位置分配RAM内存,即为程序分配尽可能彼此接近的内存段。有没有办法我可以知道我分配的内存的确切位置(内存芯片),我也想知道是否有可能以确定的方式强制分配。我对Windows和Linux都很感兴趣。此外,该项目将在Java和.NET中实现,因此我对托管API感兴趣以实现这一目标。

[我知道这可能不会转化为直接的能源消耗减少,但该项目应该是一个概念证明。]

8 个答案:

答案 0 :(得分:13)

你的工作处于错误的抽象层次。

Java(可能是.NET)是指使用句柄而不是原始指针的对象。底层Java VM可以随时在虚拟内存中移动对象; Java应用程序没有任何区别。

Win32和Linux应用程序(例如Java VM)使用虚拟地址引用内存。存在从RAM芯片上的虚拟地址到物理地址的映射。内核可以随时更改此映射(例如,如果数据被分页到磁盘然后读回到不同的内存位置),应用程序看不到任何差异。

因此,如果您使用的是Java和.NET,我不会更改您的Java / .NET应用程序来实现此目的。相反,我会改变底层的Linux内核,或者可能是Java VM。

对于原型,一种方法可能是使用mem =参数启动Linux以将内核的内存使用限制为小于您拥有的内存量,然后查看是否可以mmap备用内存(可能通过映射/ dev / mem as root?)。然后,您可以更改对Java VM中malloc()的所有调用,以使用您自己的特殊内存分配器,该分配器从该可用空间分配。

要真正实现这一点,您应该通过更改内核并保持用户空间兼容性来实现。查看memory hotplug in Linux上已完成的工作,例如http://lhms.sourceforge.net/

答案 1 :(得分:2)

如果您想在具有大型运行时的语言中尝试此操作,则必须调整该运行时的实现或编写DLL /共享对象来为您的示例应用程序执行所有内存管理。此时整个系统的行为不太可能像那些运行时的常规操作那样。

使用自定义分配器在C ++中检测引用局部性(可能很小)优点的最简单,最干净的测试环境。此环境将消除运行时数据中的几个潜在噪声原因(主要是垃圾收集)。您还将失去与启动CLR / JVM或维持其运行状态相关的任何功率开销 - 这可能在项目中受欢迎,以最大限度地降低功耗。您自然希望为测试应用程序提供一个处理器核心,以消除线程切换噪声。

编写一个自定义分配器来为您提供当前页面上预先分配的块之一应该不会太难,但考虑到要在C / C ++中实现引用的局部性,通常只使用堆栈似乎不太可能是一个你可以找到,下载和使用的。

答案 2 :(得分:1)

在C / C ++中,如果强制指向int的指针,则会告诉您该地址。但是,在Windows和Linux下,这是一个虚拟地址 - 操作系统确定到物理内存的映射,处理器中的内存管理单元执行它。

因此,如果您关心数据在物理内存中的位置,则必须询问操作系统。如果您只是关心您的数据是否在同一个MMU块中,那么请查看操作系统文档以查看它使用的大小阻塞(x86通常是4KB,但我听说孩子们现在玩的是16M巨型块?)。 / p>

Java和.NET添加了第三层,但我担心我无法帮助你。

答案 3 :(得分:1)

预先分配更大的块(比需要的话)一个选项吗?它会破坏最初的目的吗?

答案 4 :(得分:0)

我认为,如果你想要对内存分配进行这样的潮流控制,你最好使用C语言编译的语言,JVM,从硬件中隔离出语言的实际实现,包括用于数据存储的芯片选择。

答案 5 :(得分:0)

在.NET中,公开了一个COM接口,用于分析.NET应用程序,它可以为您提供详细的地址信息。我认为你需要将它与对操作系统的一些调用相结合来翻译虚拟地址。

正如zztop所说,每次垃圾收集完成时,.NET CLR都会压缩内存。虽然对于大型物体,它们不会被压实。这些是大对象堆上的对象。大对象堆可以包含从OS调用VirtualAlloc分散的许多段。

以下是分析API的几个链接:

答案 6 :(得分:0)

该方法需要专门的硬件。在普通的记忆棒中,插槽和插槽设计成尽可能地每个芯片散热。例如,每个物理芯片的每个总线字中有1位。

答案 7 :(得分:0)

这是一个有趣的话题,尽管我认为它远远超出Java或.NET等托管语言的能力。这些语言的主要原则之一是你必须管理内存,因此它们会为你抽象出来。 C / C ++在实际分配内存方面为您提供了更好的控制,但即使在这种情况下,如前所述,操作系统可以通过内存分配进行一些挥手和间接操作,这使得很难确定如何分配内存。即使这样,你也会参考实际的芯片,这更难,而且我认为这将取决于硬件。我认真考虑使用原型板,您可以在汇编级别进行编码,并实际控制每个内存单元分配,而不受编译器优化或操作系统安全实践的任何干扰。这将为您提供最有意义的结果,因为它可以让您能够控制程序的各个方面,并确定任何功耗改进都归功于您的算法而不是编译器或操作系统执行的某些不可见优化。我想这是一个研究项目(非常有趣)所以在我看来,在原型板上花费100美元肯定是值得的。