我在JamVM上工作了两周,这是一个小而强大的Java虚拟机。
现在我想弄清楚内存是如何实现的,我遇到了两个C愚蠢的问题:
char *mem = (char*)mmap(0, args->max_heap, PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON, -1, 0);
- > -1参数代表文件描述符,这是什么意思? (我已经读过mmap的人了,但还没找到,也许我误解了......)。
heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1&)~(OBJECT_GRAIN-1)) HEADER_SIZE;
- >什么是1& ?我没有在C规范中找到它......
谢谢,
晏
答案 0 :(得分:4)
回答你的第一个问题。来自man page。
fd应该是有效的文件描述符,除非设置了MAP_ANONYMOUS。如果设置了MAP_ANONYMOUS,则在Linux上忽略fd。但是,如果指定了MAP_ANONYMOUS(或MAP_ANON),某些实现要求fd为-1,便携式应用程序应确保这一点。
因为正在使用MAP_ANONYMOUS
,所以它为-1。
答案 1 :(得分:2)
当您有要映射到内存的打开文件时,可以使用文件描述符。在这种情况下,您正在创建一个匿名映射(一个没有文件支持),因此不需要文件描述符。有些实现忽略fd
匿名映射,有些要求它为-1。
第二个问题是语法错误(可能是拼写错误)。它可能应该是这样的:
heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1)
&~(OBJECT_GRAIN-1)) - HEADER_SIZE;
在这种情况下,OBJECT_GRAIN
将是2的幂,这是一种与这种力量对齐的方法。例如,如果它是8,那么~(OBJECT_GRAIN-1)
将是~7
(~00...001112
,即~11...110002
),当与值一起使用时,可以用来强制值为8的倍数小于或等于它。
事实上,它肯定是某处的转录错误(不一定是你),因为当我从here下载JamVM并查看src/alloc.c
时,我得到:
void initialiseAlloc(InitArgs *args) {
char *mem = (char*)mmap(0, args->max_heap, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANON, -1, 0);
:
<< a couple of irrelevant lines >>
:
/* Align heapbase so that start of heap + HEADER_SIZE is object aligned */
heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1)&
~(OBJECT_GRAIN-1))-HEADER_SIZE;
(请注意,您的版本也会在-
之前错过HEADER_SIZE
,这是指向转录问题的其他内容。