在C中,我可以用一个专门的内存管理器来创建一个数据结构,就像这个(非常复杂的)Judy array的开发者一样.通过对指针的直接控制,它们甚至可以在指针值本身编码附加信息.在Python,Java或C#中工作时,我故意从这种类型的解决方案中抽象出一个(或更多)的抽象级别,并且委托JIT编译器和优化运行时,在我的低级别上做出巧妙的技巧.
尽管如此,即使在这个高抽象层面上,也有一些可以被语义上认为“更接近”的东西,因此可能在较低层次上实际上更接近.例如,我想知道以下(我的括号中的猜测):
>我可以期望一个数组是相邻的内存块(是)吗?
>在相同的实例中,两个整数在同一个类的不同实例中可能比两个更接近(可能)?
>对象是否占用内存中的肮脏区域(否)?
>只有两个int字段的对象数组和具有两个int []字段的单个对象之间有什么区别? (这个例子可能是Java具体的)
我开始在Java环境中想到这些,但我的想法已经变得更加普遍了,所以我建议不要把它当作Java的问题.
>我认为可以合理的假设一个实例为字段使用的内存在一个单独的块…但不要忘记,这些字段中的一些可能是对其他对象的引用.
对于Java数组部分,Sun’s JNI documentation包含了这个评论,在关于字符串的讨论中,
For example,the Java virtual machine may not store arrays contiguously.
对于你的最后一个问题,如果你有两个int [],那么这些数组中的每个都将是一个连续的内存块,但它们在内存中可能非常“远”.如果您有一个包含两个int字段的对象数组,那么每个对象可能会有很长的距离,但每个对象中的两个整数将会相互靠近.可能更重要的是,由于每个对象的开销,您将最终获得“许多对象”解决方案的更多内存.在.NET中,您可以使用具有两个整数的自定义结构体,并具有一组数组,这些数组将所有数据保存在一个大块中.
我相信,在Java和.NET中,如果您在单个线程中快速连续分配大量小对象,那么这些对象可能具有良好的参考位置.当GC压缩一个堆时,这可能会改善 – 或者它可能会变得更糟,如果一个堆
A B C D E
被压实到
A D E B
(C被收集) – 突然之间可能已经“接近”的A和B距离很远.我不知道这是否真的发生在任何垃圾收集器(有负载在周围!),但它是可能的.
在一个受管理的环境中,您通常不会像在非管理环境中一样掌握参考的位置 – 您必须相信管理环境对管理环境有足够的好处,而且您将节省足够的时间通过编码到更高级别的平台,让您花时间优化其他地方.