【发布时间】:2014-10-26 01:53:43
【问题描述】:
我试图通过对 Neo4j 对象缓存的一些调查来了解它。我对对象缓存的第一印象来自此链接中的幻灯片: http://www.slideshare.net/thobe/an-overview-of-neo4j-internals
具体来说,缓存中的节点/关系对象应类似于幻灯片 9 或 15/42。为了验证这一点,我使用现有的图形数据库内容编写了一个简单的服务器脚本。我这样做的方法是尝试使用 sun.misc.Unsafe 查看节点/关系对象的起始虚拟地址。获取虚拟地址的程序来自以下链接: How can I get the memory location of a object in java?
public static long addressOf(Object o) throws Exception {
Object[] array = new Object[] { o };
long baseOffset = unsafe.arrayBaseOffset(Object[].class);
int addressSize = unsafe.addressSize();
long objectAddress;
switch (addressSize) {
case 4:
objectAddress = unsafe.getInt(array, baseOffset);
break;
case 8:
objectAddress = unsafe.getLong(array, baseOffset);
break;
default:
throw new Error("unsupported address size: " + addressSize);
}
return (objectAddress);
}
在 neo4j 服务器脚本(我的 main() 类)中,我通过 id 获取节点地址并按以下方式打印出地址:
void checkAddr(){
nodeAddr(0);
nodeAddr(1);
nodeAddr(2);
}
void nodeAddr(int n){
Node oneNode = graphDb.getNodeById(n);
Node[] array1 = {oneNode};
try {
long address = UnsafeUtil.addressOf(array1);
System.out.println("Addess: " + address);
} catch (Exception e) {
e.printStackTrace();
}
}
首先,我尝试使用默认情况下的软缓存提供程序。打印出节点对象 0、1 和 2 的地址是:
地址:4168500044 地址:4168502383 地址:4168502753
因此,使用第二个地址 - 第一个地址和第三个地址 - 第二个地址,我可以准确地知道一个节点占用了多少空间。在这种情况下,第一个节点对象占用 2339B,第二个占用 370B。
然后,为了查看禁用对象缓存的影响,我使用 NoCacheProvider 进行设置:
setConfig(GraphDatabaseSettings.cache_type,NoCacheProvider.NAME)
打印出来的地址是:
地址:4168488391 地址:4168490708 地址:4168491056
偏移量,计算方式与第一种情况类似:第一个节点对象占用 2317B,第二个占用 348B。
我的问题来了:
既然我使用同一张图并进行只读查询,为什么同一个节点对象的大小会发生变化?
当我禁用对象缓存时,为什么地址偏移量看起来与存在对象缓存一样?例如,在节点存储文件中,单个节点占用 9 个字节,在我的实验中不是这样。如果我获取节点对象的方式有问题,我怎样才能以正确的方式获取虚拟地址?有什么方法可以让我具体知道 mmap 节点文件在内存中的位置?
我怎样才能确切地知道节点对象中存储的内容。当我在这个链接上查看 Node.class 时: https://github.com/neo4j/neo4j/blob/1.9.8/community/kernel/src/main/java/org/neo4j/graphdb/Node.java 似乎节点对象的外观与演示幻灯片中的外观不同。而只是节点对象使用的一组函数。此外,在无对象缓存和有对象缓存的情况下,是否将节点对象作为一个整体同时带入内存?
【问题讨论】:
标签: java object neo4j graph-databases