当前位置: 技术问答>linux和unix
请教linux内存管理问题.谢谢
来源: 互联网 发布时间:2017-03-31
本文导语: 一, 书上说vmalloc()在3G+896M以上线性地址空间分配连续虚拟内存,3G到3G+896M线性地址被永久固定映射到了0--896M物理地址. 问题:如果计算机的物理内存小于896M,比如512M,那么vmalloc()是不是就没有用处了? 二,ULK(understanding t...
一, 书上说vmalloc()在3G+896M以上线性地址空间分配连续虚拟内存,3G到3G+896M线性地址被永久固定映射到了0--896M物理地址.
问题:如果计算机的物理内存小于896M,比如512M,那么vmalloc()是不是就没有用处了?
二,ULK(understanding the linux kernel)书中说:
.从0到3G的线性地址空间,无论用户态还是内核态都可以访问寻址.
.从3G到4G的线性地址空间,只有内核态可以访问寻址.
问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
问题:如果计算机的物理内存小于896M,比如512M,那么vmalloc()是不是就没有用处了?
二,ULK(understanding the linux kernel)书中说:
.从0到3G的线性地址空间,无论用户态还是内核态都可以访问寻址.
.从3G到4G的线性地址空间,只有内核态可以访问寻址.
问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
|
>>问题:如果计算机的物理内存小于896M,比如512M,那么vmalloc()是不是就没有用处了?
物理内存多大,与vmalloc()有关系吗?
vmalloc()在3G+896M~4G线性地址空间分配连续虚拟内存
3G~3G+896M线性地址被永久固定映射到了0~896M物理地址.
>>问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
没有哪里说大于896M的高端物理内存映射到了0到3G的线性地址吧
对于用户程序来说,可见的是线性地址空间,线性地址到底映射到哪个物理内存地址,只有内核才知道
线性地址到物理内存的映射是内核和MMU单元做的事
物理内存多大,与vmalloc()有关系吗?
vmalloc()在3G+896M~4G线性地址空间分配连续虚拟内存
3G~3G+896M线性地址被永久固定映射到了0~896M物理地址.
>>问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
没有哪里说大于896M的高端物理内存映射到了0到3G的线性地址吧
对于用户程序来说,可见的是线性地址空间,线性地址到底映射到哪个物理内存地址,只有内核才知道
线性地址到物理内存的映射是内核和MMU单元做的事
|
一, 书上说vmalloc()在3G+896M以上线性地址空间分配连续虚拟内存,3G到3G+896M线性地址被永久固定映射到了0--896M物理地址.
问题:如果计算机的物理内存小于896M,比如512M,那么vmalloc()是不是就没有用处了?
首先,你要弄清楚为什么kernel会给我们提供应该vmalloc函数供我们调用。试想一下,如果你的操作系统长期运行,现在我们要分配一块较大的内存(eg:2M),现在的空闲内存其实还有很多,但是就是找不到连续的内存,如果用kmalloc分配,那么肯定会失败。为什么?因为kmalloc分配的内存不仅是在虚拟空间上面是连续的,并且在物理空间上面也是连续的(因为此时的物理地址到虚拟地址是一致性映射 (32bit机器:默认phy + 0xc0000000))。那么这时候不就分配不到内存了,别急!kernel不是为我们提供了vmalloc吗?它就想用户空间分配的内存一样,分配的虚拟地址是连续的,而物理内存不一定是连续的,它分配的虚拟地址会在VMALLOC_START(896M + 8M)~VMALLOC_END之间。
所以,其实你指的3G+896M是指的虚拟空间,而当你的内存只有512M时,照样是可以映射到VMALLOC_START~VMALLOC_END之间。
二,ULK(understanding the linux kernel)书中说:
.从0到3G的线性地址空间,无论用户态还是内核态都可以访问寻址.
.从3G到4G的线性地址空间,只有内核态可以访问寻址.
问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
同样的道理,内核分配内存的虚拟空间是3G~4G(可配置),也就是说分配内存时,只有这么大的虚拟空间(0~3G给用户,当然内核可以访问用户态的内存,这里说的是分配内存)。用一个high_memory(896M)就是为了防止以下几点:
1,像上面所说的,实际内存还很多时,而连续内存很少,这样我们可以定义一个vmalloc区解决这个问题。
2,如果实际内存大于1G,那么我们需要kernel也能分配大于1G的物理地址到内核空间(3G~4G)。fix_map区可以解决这个问题
当然还有些,我也有点淡忘了。
问题:如果计算机的物理内存小于896M,比如512M,那么vmalloc()是不是就没有用处了?
首先,你要弄清楚为什么kernel会给我们提供应该vmalloc函数供我们调用。试想一下,如果你的操作系统长期运行,现在我们要分配一块较大的内存(eg:2M),现在的空闲内存其实还有很多,但是就是找不到连续的内存,如果用kmalloc分配,那么肯定会失败。为什么?因为kmalloc分配的内存不仅是在虚拟空间上面是连续的,并且在物理空间上面也是连续的(因为此时的物理地址到虚拟地址是一致性映射 (32bit机器:默认phy + 0xc0000000))。那么这时候不就分配不到内存了,别急!kernel不是为我们提供了vmalloc吗?它就想用户空间分配的内存一样,分配的虚拟地址是连续的,而物理内存不一定是连续的,它分配的虚拟地址会在VMALLOC_START(896M + 8M)~VMALLOC_END之间。
所以,其实你指的3G+896M是指的虚拟空间,而当你的内存只有512M时,照样是可以映射到VMALLOC_START~VMALLOC_END之间。
二,ULK(understanding the linux kernel)书中说:
.从0到3G的线性地址空间,无论用户态还是内核态都可以访问寻址.
.从3G到4G的线性地址空间,只有内核态可以访问寻址.
问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
同样的道理,内核分配内存的虚拟空间是3G~4G(可配置),也就是说分配内存时,只有这么大的虚拟空间(0~3G给用户,当然内核可以访问用户态的内存,这里说的是分配内存)。用一个high_memory(896M)就是为了防止以下几点:
1,像上面所说的,实际内存还很多时,而连续内存很少,这样我们可以定义一个vmalloc区解决这个问题。
2,如果实际内存大于1G,那么我们需要kernel也能分配大于1G的物理地址到内核空间(3G~4G)。fix_map区可以解决这个问题
当然还有些,我也有点淡忘了。
|
一般说来,kernel根本用不上1G的空间,也就是说1G的虚拟空间对内核已经足够了。如果你觉得不够,像路由设备(有很多的内核程序,需要很多内核空间),你可以修改内核的配置
|
将3:1的比例划分成1:1 or 跟小,这在kernel里面是允许的
|
问题:既然内核态可以访问0到4G的所有线性地址,那么所谓的大于896M的高端物理内存,内核不就可以通过0到3G的线性地址来映射访问吗?
内核0~3G的线性地址是虚拟的地址并不在内存真正的物理内存地址。
3G到3G+896M线性地址被永久固定映射到了0--896M物理地址. 3G+896M是虚拟地址。0~896M的物理地址。如果内核开启处理器MMU的话,虚拟地址到物理地址是需要进行转化的。0~3G的虚拟地址转换时,转换为不确定的物理地址,3G+896转换为固定的地址。
内核0~3G的线性地址是虚拟的地址并不在内存真正的物理内存地址。
3G到3G+896M线性地址被永久固定映射到了0--896M物理地址. 3G+896M是虚拟地址。0~896M的物理地址。如果内核开启处理器MMU的话,虚拟地址到物理地址是需要进行转化的。0~3G的虚拟地址转换时,转换为不确定的物理地址,3G+896转换为固定的地址。
|
1, 如果小于896,比如512,那么物理地址的0到512M被映射到3G到3G+512M,3G+512M到4G可由vmalloc()控制。
2,大于896M的空间可以映射到0到3G空间中,这与vmalloc关系不太大,vmalloc经常应用于设备驱动中,比如一块网卡里面有一个1M的空间,很显然你不能把这1M的空间映射到应用空间的0到3G里面啊,就只能通过vmalloc映射到搞线性空间里面,然后进行访问。
2,大于896M的空间可以映射到0到3G空间中,这与vmalloc关系不太大,vmalloc经常应用于设备驱动中,比如一块网卡里面有一个1M的空间,很显然你不能把这1M的空间映射到应用空间的0到3G里面啊,就只能通过vmalloc映射到搞线性空间里面,然后进行访问。