内核态内存管理

Ø查看内存的物理地址范围

[root@node01 ~]# cat /proc/iomem 

00000000-00000fff : reserved

00001000-0009ebff : System RAM

0009ec00-0009ffff : reserved

000a0000-000bffff : PCI Bus 0000:00

...

000dc000-000fffff : reserved

  000f0000-000fffff : System ROM

00100000-7fedffff : System RAM

  2b000000-350fffff : Crash kernel

  72600000-72d9425e : Kernel code

  72d9425f-7336817f : Kernel data

  73562000-7386efff : Kernel bss

7fee0000-7fefefff : ACPI Tables

7feff000-7fefffff : ACPI Non-volatile Storage

7ff00000-7fffffff : System RAM

 

 

Ø查看zone的信息

 [root@node01 ~]# cat /proc/zoneinfo 

Node 0, zone      DMA

  pages free     1979

        min      96

        low      120

        high     144

        scanned  0

        spanned  4095

        present  3997

        managed  3976

    nr_free_pages 1979

    nr_alloc_batch 20

    nr_inactive_anon 654

   …

Node 0, zone    DMA32

 

 

Ø查看伙伴系统的信息

root@node01 ~]# cat /proc/buddyinfo

Node 0, zone      DMA     33     15     14     5    8    5   0   2   1   2   0

Node 0, zone    DMA32   3519   5656   2514  1031  248   41   3   0   0   0   0 

[root@node01 ~]# cat /proc/pagetypeinfo 

Free pages count per migrate type at order     0   1   2   3   4   5   6   7   8   9  10 

Node    0, zone    DMA, type    Unmovable      6   6   7   5   4   1   0   1   0   0   0 

Node    0, zone    DMA, type  Reclaimable      1   0   1   0   2   3   0   0   1   1   0 

Node    0, zone    DMA, type      Movable     23   9   6   0   2   1   0   1   0   1   0 

Node    0, zone    DMA, type      Reserve      0   0   0   0   0   0   0   0   0   0   0 

Node    0, zone    DMA, type          CMA      0   0   0   0   0   0   0   0   0   0   0 

Node    0, zone    DMA, type      Isolate      0   0   0   0   0   0   0   0   0   0   0 

 

Ø查看slab的信息    pagesperslab * num_slabs *4K ==占用内存大小

[root@node01 ~]# cat /proc/slabinfo 

slabinfo - version: 2.1

# name  <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>

xfs_dqtrx       0      0    528   62    8 : tunables    0    0    0 : slabdata      0      0      0

xfs_inode   14807  20434    960   34    8 : tunables    0    0    0 : slabdata    601    601      0

...

kmalloc-96   3948   3948     96   42    1 : tunables    0    0    0 : slabdata     94     94      0

kmalloc-64  16401  19840     64   64    1 : tunables    0    0    0 : slabdata    310    310      0

kmalloc-32  12482  15616     32  128    1 : tunables    0    0    0 : slabdata    122    122      0

kmalloc-16  32426  49664     16  256    1 : tunables    0    0    0 : slabdata    194    194      0

kmalloc-8    8704   8704      8  512    1 : tunables    0    0    0 : slabdata     17     17      0

 

 

 

 

[root@node01 ~]# cat /proc/vmallocinfo 

0xffffb751c0000000-0xffffb751c0002000    8192 hpet_enable+0x2d/0x317 phys=fed00000 ioremap

0xffffb751c0002000-0xffffb751c0203000 2101248 alloc_large_system_hash+0x188/0x25c pages=512 vmalloc N0=512

0xffffb751c0203000-0xffffb751c0304000 1052672 alloc_large_system_hash+0x188/0x25c pages=256 vmalloc N0=256

0xffffb751c0304000-0xffffb751c030d000   36864 alloc_large_system_hash+0x188/0x25c pages=8 vmalloc N0=8

0xffffb751c030d000-0xffffb751c0316000   36864 alloc_large_system_hash+0x188/0x25c pages=8 vmalloc N0=8

0xffffb751c0316000-0xffffb751c0318000    8192 acpi_os_map_memory+0xfd/0x155 phys=7feff000 ioremap

0xffffb751c031c000-0xffffb751c031e000    8192 usb_hcd_pci_probe+0x143/0x560 phys=fd5bf000 ioremap

0xffffb751c0336000-0xffffb751c0357000  135168 raw_init+0x41/0x141 pages=32 vmalloc N0=32

0xffffb751c0357000-0xffffb751c035c000   20480 agp_add_bridge+0x2da/0x480 pages=4 vmalloc N0=4

0xffffb751c03a8000-0xffffb751c03aa000    8192 vmballoon_work+0x1f9/0x6ff [vmw_balloon] vmap

 

用户态内存映射

以32位X86系统为例,每个用户态进程的地址空间为3G,在需要时,操作系统为地址空间映射物理内存,供进程使用,一般的过程是:

1、进程通过malloc()函数申请内存,用户态的内存管理算法通过brk()/mmap()系统调用,会得到一段地址空间,经过内存管理算法对空间进行划分,返回一个虚拟地址;

2、进程访问虚拟地址,由于虚拟地址没有映射的物理内存,会产生缺页异常;

3、操作系统处理缺页异常,通过伙伴系统算法分配物理页,设置页表项,将物理地址映射到虚拟地址上,返回用户态进程继续运行;

4、用户态进程此时就可以访问虚拟地址了。

缺页异常的处理,对于用户态进程来说是透明的,它并不感知这一过程。并且,虚拟地址一旦映射,操作系统里会保存期页表项,下次访问不会再次产生缺页异常。

 

 

1、空闲内存很少,怎样确定谁占用了大量内存?

cat /proc/meminfo,先大致确定是哪些部分占用的内存多,然后再详细查询

MemTotal:        1863100 kB

MemFree:         1495220 kB

MemAvailable:    1522176 kB

Buffers:            2108 kB

Cached:           147860 kB   // 1)内存文件系统及文件缓存占用的内存   echo 3 > /xx/xx/vm/drop_cache

SwapCached:            0 kB

AnonPages:         72496 kB   // 2)AnonPages及Mapped是用户态占用的内存

Mapped:            36128 kB

Slab:              68760 kB   // 3)slab分配器占用的内存,具体查询/proc/slabinfo

KernelStack:        4480 kB   // 内核线程栈占用的内存

PageTables:         8332 kB   // 页表项占用的内存

VmallocTotal:   34359738367 kB

VmallocUsed:      180368 kB   // 4)vmalloc空间的使用情况,并不完全是内存,具体查询/proc/vmallocinfo

 

 

1、空闲内存剩余还有很多,为什么kmalloc失败?

1)注意kmalloc申请的内存大小;可能情况是系统剩余内存还很多,但是碎片化比较严重,已经没有这么大的连续内存了。

2)如果是32位的设备,要注意kmalloc是只能申请lowmem(DMA/NORMAL)的,有可能Free内存比较多,但是lowmem已经很少了

通过查看/proc/buddyinfo来确认上述两点

2、空闲内存剩余还有很多,为什么malloc失败?

1)空闲内存不够,malloc不会返回NULL;而是在访问内存时,触发OOM。

2)用户态malloc返回NULL,一般是进程的地址空间不够了,在32位的系统上地址空间小,容易出现这样的问题。通过/proc/<pid>/maps来查看地址空间的使用情况。

 

有时候,不小心知道了一些事,才发现自己所在乎的事是那么可笑。
原文地址:https://www.cnblogs.com/axjlxy/p/15404006.html