smaps 内存分布
大虾们,晚上好~我在分析一个程序内存波动的时候,抓取了/proc/pid/smaps数据
发现有一块64M左右的内存,其没有权限,但又是private
像下面这个样子
400df000-4048c000 ---p 00000000 00:00 0
请教下这段内存是用来干什么的?
为什么属于当前进程,当前进程又没有权限去rw呢?
实在不明白,,, 这种段一般都是为了隔离其它的段,防止其它段越界访问的。 回复 1# hhuccpj
64M? 是linux 64 bit? 那是glibc 给内存池分配的, 64位linux glibc 会给每个线程分配一个arena, 每个arena至少有1个64M的heap, 应该就是这个heap. 今天我发现这块会慢慢被修改为re-p,应该不是保护 今天我发现这块内存会满满被修改为rw-p。看起来像是先mmap,flag设置为空了,再然后慢慢mprotect修改。上午分析我也在想应该是内存池。我是64位的机子。但我内存明明是够的,为什么会触发再来一块呢?思考中,,, 回复 5# hhuccpj
小伙很有前途啊, 观察问题很仔细, 从glibc代码来看, 的确是一开始映射的flags为0, 后来通过mprotect改成rw的
你如果用strace跟踪应该能抓到这个过程。
上代码:
static heap_info *
internal_function
#if __STD_C
new_heap(size_t size, size_t top_pad)
#else
new_heap(size, top_pad) size_t size, top_pad;
#endif
{
size_t page_mask = malloc_getpagesize - 1;
char *p1, *p2;
unsigned long ul;
heap_info *h;
if(size+top_pad < HEAP_MIN_SIZE)
size = HEAP_MIN_SIZE;
else if(size+top_pad <= HEAP_MAX_SIZE)
size += top_pad;
else if(size > HEAP_MAX_SIZE)
return 0;
else
size = HEAP_MAX_SIZE;
size = (size + page_mask) & ~page_mask;
/* A memory region aligned to a multiple of HEAP_MAX_SIZE is needed.
No swap space needs to be reserved for the following large
mapping (on Linux, this is the case for all non-writable mappings
anyway). */
p2 = MAP_FAILED;
if(aligned_heap_area) {
p2 = (char *)MMAP(aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
MAP_PRIVATE|MAP_NORESERVE);
aligned_heap_area = NULL;
if (p2 != MAP_FAILED && ((unsigned long)p2 & (HEAP_MAX_SIZE-1))) {
munmap(p2, HEAP_MAX_SIZE);
p2 = MAP_FAILED;
}
}
if(p2 == MAP_FAILED) {
p1 = (char *)MMAP(0, HEAP_MAX_SIZE<<1, PROT_NONE,
MAP_PRIVATE|MAP_NORESERVE);
if(p1 != MAP_FAILED) {
p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1))
& ~(HEAP_MAX_SIZE-1));
ul = p2 - p1;
if (ul)
munmap(p1, ul);
else
aligned_heap_area = p2 + HEAP_MAX_SIZE;
munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
} else {
/* Try to take the chance that an allocation of only HEAP_MAX_SIZE
is already aligned. */
p2 = (char *)MMAP(0, HEAP_MAX_SIZE, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE);
if(p2 == MAP_FAILED)
return 0;
if((unsigned long)p2 & (HEAP_MAX_SIZE-1)) {
munmap(p2, HEAP_MAX_SIZE);
return 0;
}
}
}
if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) {
munmap(p2, HEAP_MAX_SIZE);
return 0;
}
h = (heap_info *)p2;
h->size = size;
h->mprotect_size = size;
THREAD_STAT(stat_n_heaps++);
return h;
} 哈哈,谢谢夸奖,我怎么感觉有点飘的感觉,开个玩笑。我是想strace抓一下的,但这个问题只在高caps长时间下才发生,strace上去后性能上不去。我怀疑我用的下层平台有人改东西了,如大家所述的话,应该有动态加减线程数 回复 7# hhuccpj
有两种情况glibc会创建新的64M heap,
一种是新建线程如果在堆上分配内存会触发glibc分配, 另一种是老线程前面的64M heap用光了也会新分配新的,多个heap会穿成一个链表。 嗯,,我生日0729,比你晚一天,大哥在上,请受小弟一拜 回复 9# hhuccpj
你哪年的,还不知道谁大呢。我84
页:
[1]
2