Linux系统的内存分配竹节的几个问题
谁不熟悉竹节学生可以跳过第一个,和涉及的东西更细致。总之,竹节的结构是一个N(CPU数)kmem_cache_cpu和一个kmem_cache_cpu kmem_cache_node.the目的是提高CPU从技术层面到缓存,并没有在同一页上的一个肮脏的记忆,也就是说,它不是由多个CPU在同一时间。我实施这一机制实现手动在Windows中,有一个问题,当多个kmem_cache_cpu打开。
1。当对象被释放,判断当前kmem_cache_cpu页位于
2。如果是,直接插入它。
三.如果没有,则释放到邻居节点
如果它是一个单一的kmem_cache_cpu,这是没有问题的,但在多kmem_cache_cpu,它很可能会发布,kmem_cache_cpu已经对邻居节点的页面,例如 uff1a
假设一个网页的地址是0-9,
kmem_cache_cpu1,拿着一页,闲置情况的A0 - A5
kmem_cache_cpu2,持有B页,
当kmem_cache_cpu2是执行,一个网页的地址A6的发布,和程序检测到一个非B页面,这是直接释放到邻居节点。此时,该页面已被切成两段,在一个共同的邻居节点。在这个时候,它是在记忆肮脏的增加。在代码仔细看了一下,这部分的源代码:
结构kmem_cache_cpu {
void * *自由列表;指向第一个免费每CPU / * * /对象
结构页*页面,我们从中得到它;
页面的int节点节点;(或- 1用于调试)。
unsigned int偏移freepointer偏移(在词; / * * /单位)
unsigned int objsize;大小的一个对象(从 / kmem_cache)。
# ifdef config_slub_stats
无符号数据nr_slub_stat_items } {;
# endif
};
请注意结构页*,以前一直忽略它,而事实是在分配函数中,
如果数据是无效的,一页页的地址将查询。
2011年1月15日增加
仔细看看,我想这里有个虫子。
分两步释放
1)使用本地页面
2)节点节点
应用程序更复杂
1)以当地的自由列表
2)在这页页上行走
3)步行邻居节点
4)行走系统
做一些看起来被释放的事情。
1)如果页面和自由列表是空的,然后走deactivate_slab();
有很多在deactivate_slab兼容的判断,他们应该放弃一个又一个。这是最痛苦的阅读源代码。
一个值页面->使用使用。这是一个奇怪的价值。它是指在kmem_cache_cpu电流+使用的对象,如果它被释放。
一个,所以你看不到他的+ +。
1)如果页面->使用大于0,和自由有价值,加入的邻居,这估计是与自由列表不是空的先前判决的兼容
2)另一方面,添加到邻居列表中。
3)如果当前邻居已满,则释放它。
2)如果空闲列表是空的,页面是不是空的,它是可能的,其他kmem_cache_cpu释放该对象,然后load_freelist:
问题1:加入邻居表和释放冲突,加入邻居表。从条件的角度来看,其实所有的两取决于页面->加入自由列表是空的。然而,deactivate_slab加入邻居节点后,页面->自由列表不处理。如果此时有对象释放,会导致重复加入吗
问题是我犯了一个错误。如果页面->使用= = 0,对象已经发布,它将不会再次触发。
问题二:一例kmem_cache_cpu,元素的释放是在共同邻居的页面,可能是kmem_cache_cpu其他直接访问,从而导致2种不同的kmem_cache_cpu共享相同的页面,这是违反一个缓存里面打功能。