日期内核版本架构作者GitHubCSDN
2016-08-31Linux-4.7X86 & armgatiemeLinuxDeviceDriversLinux内存管理

2017-11-05 最新更新
更新了 struct zone 结构体的字段描述, 更详细, 更清晰

1 前景回顾


前面我们讲到服务器体系(SMP, NUMA, MPP)与共享存储器架构(UMA和NUMA)

1.1 UMA和NUMA两种模型


共享存储型多处理机有两种模型

  • 均匀存储器存取(Uniform-Memory-Access,简称UMA)模型

  • 非均匀存储器存取(Nonuniform-Memory-Access,简称NUMA)模型

UMA模型

物理存储器被所有处理机均匀共享。所有处理机对所有存储字具有相同的存取时间,这就是为什么称它为均匀存储器存取的原因。每台处理机可以有私用高速缓存,外围设备也以一定形式共享。

NUMA模型

NUMA模式下,处理器被划分成多个”节点”(node), 每个节点被分配有的本地存储器空间。 所有节点中的处理器都可以访问全部的系统物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多。

1.2 (N)UMA模型中linux内存的机构


非一致存储器访问(NUMA)模式下

  • 处理器被划分成多个”节点”(node), 每个节点被分配有的本地存储器空间. 所有节点中的处理器都可以访问全部的系统物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多

  • 内存被分割成多个区域(BANK,也叫”簇”),依据簇与处理器的”距离”不同, 访问不同簇的代码也会不同. 比如,可能把内存的一个簇指派给每个处理器,或则某个簇和设备卡很近,很适合DMA,那么就指派给该设备。因此当前的多数系统会把内存系统分割成2块区域,一块是专门给CPU去访问,一块是给外围设备板卡的DMA去访问

在UMA系统中, 内存就相当于一个只使用一个NUMA节点来管理整个系统的内存. 而内存管理的其他地方则认为他们就是在处理一个(伪)NUMA系统.

1.3 Linux如何描述物理内存


Linux把物理内存划分为三个层次来管理

层次描述
存储节点(Node)CPU被划分为多个节点(node), 内存则被分簇, 每个CPU对应一个本地物理内存, 即一个CPU-node对应一个内存簇bank,即每个内存簇被认为是一个节点
管理区(Zone)每个物理内存节点node被划分为多个内存管理区域, 用于表示不同范围的内存, 内核可以使用不同的映射方式映射物理内存
页面(Page)内存被细分为多个页面帧, 页面是最基本的页面分配的单位 |

1.4 用pd_data_t描述内存节点node


CPU被划分为多个节点(node), 内存则被分簇, 每个CPU对应一个本地物理内存, 即一个CPU-node对应一个内存簇bank,即每个内存簇被认为是一个节点

系统的物理内存被划分为几个节点(node), 一个node对应一个内存簇bank,即每个内存簇被认为是一个节点

  • 首先, 内存被划分为结点. 每个节点关联到系统中的一个处理器, 内核中表示为pg_data_t的实例. 系统中每个节点被链接到一个以NULL结尾的pgdat_list链表中<而其中的每个节点利用pg_data_tnode_next字段链接到下一节.而对于PC这种UMA结构的机器来说, 只使用了一个成为contig_page_data的静态pg_data_t结构.

内存中的每个节点都是由pg_data_t描述,而pg_data_t由struct pglist_data定义而来, 该数据结构定义在include/linux/mmzone.h, line 615

在分配一个页面时, Linux采用节点局部分配的策略, 从最靠近运行中的CPU的节点分配内存, 由于进程往往是在同一个CPU上运行, 因此从当前节点得到的内存很可能被用到

1.5 今日内容(内存管理域zone)


为了支持NUMA模型,也即CPU对不同内存单元的访问时间可能不同,此时系统的物理内存被划分为几个节点(node), 一个node对应一个内存簇bank,即每个内存簇被认为是一个节点

  • 首先, 内存被划分为结点. 每个节点关联到系统中的一个处理器, 内核中表示为pg_data_t的实例. 系统中每个节点被链接到一个以NULL结尾的pgdat_list链表中<而其中的每个节点利用pg_data_tnode_next字段链接到下一节.而对于PC这种UMA结构的机器来说, 只使用了一个成为contig_page_data的静态pg_data_t结构.

  • 接着各个节点又被划分为内存管理区域, 一个管理区域通过struct zone_struct描述, 其被定义为zone_t, 用以表示内存的某个范围, 低端范围的16MB被描述为ZONE_DMA, 某些工业标准体系结构中的(ISA)设备需要用到它, 然后是可直接映射到内核的普通内存域ZONE_NORMAL,最后是超出了内核段的物理地址域ZONE_HIGHMEM, 被称为高端内存. 是系统中预留的可用内存空间, 不能被内核直接映射.

下面我们就来详解讲讲内存管理域的内容zone

2 为什么要将内存node分成不同的区域zone


NUMA结构下, 每个处理器CPU与一个本地内存直接相连, 而不同处理器之前则通过总线进行进一步的连接, 因此相对于任何一个CPU访问本地内存的速度比访问远程内存的速度要快, 而Linux为了兼容NUMAJ结构, 把物理内存相依照CPU的不同node分成簇, 一个CPU-node对应一个本地内存pgdata_t.

这样已经很好的表示物理内存了, 在一个理想的计算机系统中, 一个页框就是一个内存的分配单元, 可用于任何事情:存放内核数据, 用户数据和缓冲磁盘数据等等. 任何种类的数据页都可以存放在任页框中, 没有任何限制.


但是Linux内核又把各个物理内存节点分成个不同的管理区域zone, 这是为什么呢?

因为实际的计算机体系结构有硬件的诸多限制, 这限制了页框可以使用的方式. 尤其是, Linux内核必须处理80x86体系结构的两种硬件约束.

  • ISA总线的直接内存存储DMA处理器有一个严格的限制 : 他们只能对RAM的前16MB进行寻址

  • 在具有大容量RAM的现代32位计算机中, CPU不能直接访问所有的物理地址, 因为线性地址空间太小, 内核不可能直接映射所有物理内存到线性地址空间, 我们会在后面典型架构(x86)上内存区域划分详细讲解x86_32上的内存区域划分

因此Linux内核对不同区域的内存需要采用不同的管理方式和映射方式, 因此内核将物理地址或者成用zone_t表示的不同地址区域

3 内存管理区类型zone_type


前面我们说了由于硬件的一些约束, 低端的一些地址被用于DMA, 而在实际内存大小超过了内核所能使用的现行地址的时候, 一些高地址处的物理地址不能简单持久的直接映射到内核空间. 因此内核将内存的节点node分成了不同的内存区域方便管理和映射.

Linux使用enum zone_type来标记内核所支持的所有内存区域

3.1 内存区域类型zone_type


zone_type结构定义在include/linux/mmzone.h, 其基本信息如下所示

enum zone_type
{
#ifdef CONFIG_ZONE_DMAZONE_DMA,
#endif#ifdef CONFIG_ZONE_DMA32ZONE_DMA32,
#endifZONE_NORMAL,#ifdef CONFIG_HIGHMEMZONE_HIGHMEM,
#endifZONE_MOVABLE,
#ifdef CONFIG_ZONE_DEVICEZONE_DEVICE,
#endif__MAX_NR_ZONES};

不同的管理区的用途是不一样的,ZONE_DMA类型的内存区域在物理内存的低端,主要是ISA设备只能用低端的地址做DMA操作。ZONE_NORMAL类型的内存区域直接被内核映射到线性地址空间上面的区域(line address space),ZONE_HIGHMEM将保留给系统使用,是系统中预留的可用内存空间,不能被内核直接映射。

3.2 不同的内存区域的作用


在内存中,每个簇所对应的node又被分成的称为管理区(zone)的块,它们各自描述在内存中的范围。一个管理区(zone)由struct zone结构体来描述,在linux-2.4.37之前的内核中是用typedef struct zone_struct zone_t数据结构来描述)

管理区的类型用zone_type表示, 有如下几种

管理内存域描述
ZONE_DMA标记了适合DMA的内存域. 该区域的长度依赖于处理器类型. 这是由于古老的ISA设备强加的边界. 但是为了兼容性, 现代的计算机也可能受此影响
ZONE_DMA32标记了使用32位地址字可寻址, 适合DMA的内存域. 显然, 只有在53位系统中ZONE_DMA32才和ZONE_DMA有区别, 在32位系统中, 本区域是空的, 即长度为0MB, 在Alpha和AMD64系统上, 该内存的长度可能是从0到4GB
ZONE_NORMAL标记了可直接映射到内存段的普通内存域. 这是在所有体系结构上保证会存在的唯一内存区域, 但无法保证该地址范围对应了实际的物理地址. 例如, 如果AMD64系统只有两2G内存, 那么所有的内存都属于ZONE_DMA32范围, 而ZONE_NORMAL则为空
ZONE_HIGHMEM标记了超出内核虚拟地址空间的物理内存段, 因此这段地址不能被内核直接映射
ZONE_MOVABLE内核定义了一个伪内存域ZONE_MOVABLE, 在防止物理内存碎片的机制memory migration中需要使用该内存域. 供防止物理内存碎片的极致使用
ZONE_DEVICE为支持热插拔设备而分配的Non Volatile Memory非易失性内存
MAX_NR_ZONES充当结束标记, 在内核中想要迭代系统中所有内存域, 会用到该常亮

根据编译时候的配置, 可能无需考虑某些内存域. 例如在64位系统中, 并不需要高端内存, 因为AM64的linux采用4级页表,支持的最大物理内存为64TB, 对于虚拟地址空间的划分,将0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000这128T地址用于用户空间;而0xffff,8000,0000,0000以上的128T为系统空间地址, 这远大于当前我们系统中的内存空间, 因此所有的物理地址都可以直接映射到内核中, 不需要高端内存的特殊映射. 可以参见Documentation/x86/x86_64/mm.txt
`

ZONE_MOVABLE和ZONE_DEVICE其实是和其他的ZONE的用途有异,

  • ZONE_MOVABLE在防止物理内存碎片的机制中需要使用该内存区域,

  • ZONE_DEVICE笔者也第一次知道了,理解有错的话欢迎大家批评指正, 这个应该是为支持热插拔设备而分配的Non Volatile Memory非易失性内存,

关于ZONE_DEVICE, 具体的信息可以参见[ATCH v2 3/9] mm: ZONE_DEVICE for “device memory”](https://lkml.org/lkml/2015/8/25/844)

While pmem is usable as a block device or via DAX mappings to userspace
there are several usage scenarios that can not target pmem due to its
lack of struct page coverage. In preparation for “hot plugging” pmem
into the vmemmap add ZONE_DEVICE as a new zone to tag these pages
separately from the ones that are subject to standard page allocations.
Importantly “device memory” can be removed at will by userspace
unbinding the driver of the device.

3.3 典型架构(x86)上内存区域划分


对于x86机器,管理区(内存区域)类型如下分布

类型区域
ZONE_DMA0~15MB
ZONE_NORMAL16MB~895MB
ZONE_HIGHMEM896MB~物理内存结束

而由于32位系统中, Linux内核虚拟地址空间只有1G, 而0~895M这个986MB被用于DMA和直接映射, 剩余的物理内存被成为高端内存. 那内核是如何借助剩余128MB高端内存地址空间是如何实现访问可以所有物理内存?

当内核想访问高于896MB物理地址内存时,从0xF8000000 ~ 0xFFFFFFFF地址空间范围内找一段相应大小空闲的逻辑地址空间,借用一会。借用这段逻辑地址空间,建立映射到想访问的那段物理内存(即填充内核PTE页面表),临时用一会,用完后归还。这样别人也可以借用这段地址空间访问其他物理内存,实现了使用有限的地址空间,访问所有所有物理内存

关于高端内存的内容, 我们后面会专门抽出一章进行讲解

因此, 传统和X86_32位系统中, 前16M划分给ZONE_DMA, 该区域包含的页框可以由老式的基于ISAS的设备通过DMA使用”直接内存访问(DMA)”, ZONE_DMA和ZONE_NORMAL区域包含了内存的常规页框, 通过把他们线性的映射到现行地址的第4个GB, 内核就可以直接进行访问, 相反ZONE_HIGHME包含的内存页不能由内核直接访问, 尽管他们也线性地映射到了现行地址空间的第4个GB. 在64位体系结构中, 线性地址空间的大小远远好过了系统的实际物理地址, 内核可知直接将所有的物理内存映射到线性地址空间, 因此64位体系结构上ZONE_HIGHMEM区域总是空的.

4 管理区结构zone_t


一个管理区(zone)由struct zone结构体来描述(linux-3.8~目前linux4.5),而在linux-2.4.37之前的内核中是用struct zone_struct数据结构来描述), 他们都通过typedef被重定义为zone_t类型

zone对象用于跟踪诸如页面使用情况的统计数, 空闲区域信息和锁信息

里面保存着内存使用状态信息,如page使用统计, 未使用的内存区域,互斥访问的锁(LOCKS)等.

4.1 struct zone管理域数据结构


struct zonelinux/mmzone.h中定义, 在linux-4.7的内核中可以使用include/linux/mmzone.h来查看其定义

struct zone
{/* Read-mostly fields *//* zone watermarks, access with *_wmark_pages(zone) macros */unsigned long watermark[NR_WMARK];unsigned long nr_reserved_highatomic;/** We don't know if the memory that we're going to allocate will be* freeable or/and it will be released eventually, so to avoid totally* wasting several GB of ram we must reserve some of the lower zone* memory (otherwise we risk to run OOM on the lower zones despite* there being tons of freeable ram on the higher zones).  This array is* recalculated at runtime if the sysctl_lowmem_reserve_ratio sysctl* changes.* 分别为各种内存域指定了若干页* 用于一些无论如何都不能失败的关键性内存分配。*/long lowmem_reserve[MAX_NR_ZONES];#ifdef CONFIG_NUMAint node;
#endif/** The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on* this zone's LRU.  Maintained by the pageout code.* 不活动页的比例,* 接着是一些很少使用或者大部分情况下是只读的字段:* wait_table wait_table_hash_nr_entries wait_table_bits* 形成等待列队,可以等待某一页可供进程使用  */unsigned int inactive_ratio;/*  指向这个zone所在的pglist_data对象  */struct pglist_data      *zone_pgdat;/*/这个数组用于实现每个CPU的热/冷页帧列表。内核使用这些列表来保存可用于满足实现的“新鲜”页。但冷热页帧对应的高速缓存状态不同:有些页帧很可能在高速缓存中,因此可以快速访问,故称之为热的;未缓存的页帧与此相对,称之为冷的。*/struct per_cpu_pageset __percpu *pageset;/** This is a per-zone reserve of pages that are not available* to userspace allocations.* 每个区域保留的不能被用户空间分配的页面数目*/unsigned long       totalreserve_pages;#ifndef CONFIG_SPARSEMEM/** Flags for a pageblock_nr_pages block. See pageblock-flags.h.* In SPARSEMEM, this map is stored in struct mem_section*/unsigned long       *pageblock_flags;
#endif /* CONFIG_SPARSEMEM */#ifdef CONFIG_NUMA/** zone reclaim becomes active if more unmapped pages exist.*/unsigned long       min_unmapped_pages;unsigned long       min_slab_pages;
#endif /* CONFIG_NUMA *//* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT* 只内存域的第一个页帧 */unsigned long       zone_start_pfn;/** spanned_pages is the total pages spanned by the zone, including* holes, which is calculated as:*      spanned_pages = zone_end_pfn - zone_start_pfn;** present_pages is physical pages existing within the zone, which* is calculated as:*      present_pages = spanned_pages - absent_pages(pages in holes);** managed_pages is present pages managed by the buddy system, which* is calculated as (reserved_pages includes pages allocated by the* bootmem allocator):*      managed_pages = present_pages - reserved_pages;** So present_pages may be used by memory hotplug or memory power* management logic to figure out unmanaged pages by checking* (present_pages - managed_pages). And managed_pages should be used* by page allocator and vm scanner to calculate all kinds of watermarks* and thresholds.** Locking rules:** zone_start_pfn and spanned_pages are protected by span_seqlock.* It is a seqlock because it has to be read outside of zone->lock,* and it is done in the main allocator path.  But, it is written* quite infrequently.** The span_seq lock is declared along with zone->lock because it is* frequently read in proximity to zone->lock.  It's good to* give them a chance of being in the same cacheline.** Write access to present_pages at runtime should be protected by* mem_hotplug_begin/end(). Any reader who can't tolerant drift of* present_pages should get_online_mems() to get a stable value.** Read access to managed_pages should be safe because it's unsigned* long. Write access to zone->managed_pages and totalram_pages are* protected by managed_page_count_lock at runtime. Idealy only* adjust_managed_page_count() should be used instead of directly* touching zone->managed_pages and totalram_pages.*/unsigned long       managed_pages;unsigned long       spanned_pages;             /*  总页数,包含空洞  */unsigned long       present_pages;              /*  可用页数,不包哈空洞  *//*  指向管理区的传统名字, "DMA", "NROMAL"或"HIGHMEM" */const char          *name;#ifdef CONFIG_MEMORY_ISOLATION/** Number of isolated pageblock. It is used to solve incorrect* freepage counting problem due to racy retrieving migratetype* of pageblock. Protected by zone->lock.*/unsigned long       nr_isolate_pageblock;
#endif#ifdef CONFIG_MEMORY_HOTPLUG/* see spanned/present_pages for more description */seqlock_t           span_seqlock;
#endif/** wait_table       -- the array holding the hash table* wait_table_hash_nr_entries   -- the size of the hash table array* wait_table_bits      -- wait_table_size == (1 << wait_table_bits)** The purpose of all these is to keep track of the people* waiting for a page to become available and make them* runnable again when possible. The trouble is that this* consumes a lot of space, especially when so few things* wait on pages at a given time. So instead of using* per-page waitqueues, we use a waitqueue hash table.** The bucket discipline is to sleep on the same queue when* colliding and wake all in that wait queue when removing.* When something wakes, it must check to be sure its page is* truly available, a la thundering herd. The cost of a* collision is great, but given the expected load of the* table, they should be so rare as to be outweighed by the* benefits from the saved space.** __wait_on_page_locked() and unlock_page() in mm/filemap.c, are the* primary users of these fields, and in mm/page_alloc.c* free_area_init_core() performs the initialization of them.*//*  进程等待队列的散列表, 这些进程正在等待管理区中的某页  */wait_queue_head_t       *wait_table;/*  等待队列散列表中的调度实体数目  */unsigned long       wait_table_hash_nr_entries;/*  等待队列散列表数组大小, 值为2^order  */unsigned long       wait_table_bits;ZONE_PADDING(_pad1_)/* free areas of different sizes页面使用状态的信息,以每个bit标识对应的page是否可以分配是用于伙伴系统的,每个数组元素指向对应阶也表的数组开头以下是供页帧回收扫描器(page reclaim scanner)访问的字段scanner会跟据页帧的活动情况对内存域中使用的页进行编目如果页帧被频繁访问,则是活动的,相反则是不活动的,在需要换出页帧时,这样的信息是很重要的:   */struct free_area    free_area[MAX_ORDER];/* zone flags, see below 描述当前内存的状态, 参见下面的enum zone_flags结构 */unsigned long       flags;/* Write-intensive fields used from the page allocator, 保存该描述符的自旋锁  */spinlock_t          lock;ZONE_PADDING(_pad2_)/* Write-intensive fields used by page reclaim *//* Fields commonly accessed by the page reclaim scanner */spinlock_t          lru_lock;   /* LRU(最近最少使用算法)活动以及非活动链表使用的自旋锁  */struct lruvec       lruvec;/** When free pages are below this point, additional steps are taken* when reading the number of free pages to avoid per-cpu counter* drift allowing watermarks to be breached* 在空闲页的数目少于这个点percpu_drift_mark的时候* 当读取和空闲页数一样的内存页时,系统会采取额外的工作,* 防止单CPU页数漂移,从而导致水印被破坏。*/unsigned long percpu_drift_mark;#if defined CONFIG_COMPACTION || defined CONFIG_CMA/* pfn where compaction free scanner should start */unsigned long       compact_cached_free_pfn;/* pfn where async and sync compaction migration scanner should start */unsigned long       compact_cached_migrate_pfn[2];
#endif#ifdef CONFIG_COMPACTION/** On compaction failure, 1<<compact_defer_shift compactions* are skipped before trying again. The number attempted since* last failure is tracked with compact_considered.*/unsigned int        compact_considered;unsigned int        compact_defer_shift;int                       compact_order_failed;
#endif#if defined CONFIG_COMPACTION || defined CONFIG_CMA/* Set to true when the PG_migrate_skip bits should be cleared */bool            compact_blockskip_flush;
#endifbool            contiguous;ZONE_PADDING(_pad3_)/* Zone statistics 内存域的统计信息, 参见后面的enum zone_stat_item结构 */atomic_long_t       vm_stat[NR_VM_ZONE_STAT_ITEMS];
} ____cacheline_internodealigned_in_smp;
字段描述
watermark每个 zone 在系统启动时会计算出 3 个水位值, 分别为 WMAKR_MIN, WMARK_LOW, WMARK_HIGH 水位, 这在页面分配器和 kswapd 页面回收中会用到
lowmem_reserve[MAX_NR_ZONES]zone 中预留的内存, 为了防止一些代码必须运行在低地址区域,所以事先保留一些低地址区域的内存
pagesetpage管理的数据结构对象,内部有一个page的列表(list)来管理。每个CPU维护一个page list,避免自旋锁的冲突。这个数组的大小和NR_CPUS(CPU的数量)有关,这个值是编译的时候确定的
lock对zone并发访问的保护的自旋锁
free_area[MAX_ORDER]页面使用状态的信息,以每个bit标识对应的page是否可以分配
lru_lockLRU(最近最少使用算法)的自旋锁
wait_table待一个page释放的等待队列哈希表。它会被wait_on_page(),unlock_page()函数使用. 用哈希表,而不用一个等待队列的原因,防止进程长期等待资源
wait_table_hash_nr_entries哈希表中的等待队列的数量
zone_pgdat指向这个zone所在的pglist_data对象
zone_start_pfn和node_start_pfn的含义一样。这个成员是用于表示zone中的开始那个page在物理内存中的位置的present_pages, spanned_pages: 和node中的类似的成员含义一样
namezone的名字,字符串表示: “DMA”,”Normal” 和”HighMem”
totalreserve_pages每个区域保留的不能被用户空间分配的页面数目
ZONE_PADDING由于自旋锁频繁的被使用,因此为了性能上的考虑,将某些成员对齐到cache line中,有助于提高执行的性能。使用这个宏,可以确定zone->lock,zone->lru_lock,zone->pageset这些成员使用不同的cache line.
managed_pageszone 中被伙伴系统管理的页面数量
spanned_pageszone 中包含的页面数量
present_pageszone 中实际管理的页面数量. 对一些体系结构来说, 其值和 spanned_pages 相等
lruvecLRU 链表集合
vm_statzone 计数

4.2 ZONE_PADDING将数据保存在高速缓冲行


该结构比较特殊的地方是它由ZONE_PADDING分隔的几个部分. 这是因为堆zone结构的访问非常频繁. 在多处理器系统中, 通常会有不同的CPU试图同时访问结构成员. 因此使用锁可以防止他们彼此干扰, 避免错误和不一致的问题. 由于内核堆该结构的访问非常频繁, 因此会经常性地获取该结构的两个自旋锁zone->lock和zone->lru_lock

由于 struct zone 结构经常被访问到, 因此这个数据结构要求以 L1 Cache 对齐. 另外, 这里的 ZONE_PADDING( )zone->lockzone_lru_lock 这两个很热门的锁可以分布在不同的 Cahe Line 中. 一个内存 node 节点最多也就几个 zone, 因此 zone 数据结构不需要像 struct page 一样关心数据结构的大小, 因此这里的 ZONE_PADDING( ) 可以理解为用空间换取时间(性能). 在内存管理开发过程中, 内核开发者逐渐发现有一些自选锁竞争会非常厉害, 很难获取. 像 zone->lockzone->lru_lock 这两个锁有时需要同时获取锁. 因此保证他们使用不同的 Cache Line 是内核常用的一种优化技巧.

那么数据保存在CPU高速缓存中, 那么会处理得更快速. 高速缓冲分为行, 每一行负责不同的内存区. 内核使用ZONE_PADDING宏生成”填充”字段添加到结构中, 以确保每个自旋锁处于自身的缓存行中

ZONE_PADDING宏定义在nclude/linux/mmzone.h?v4.7, line 105

/** zone->lock and zone->lru_lock are two of the hottest locks in the kernel.* So add a wild amount of padding here to ensure that they fall into separate* cachelines.  There are very few zone structures in the machine, so space* consumption is not a concern here.*/
#if defined(CONFIG_SMP)struct zone_padding{char x[0];} ____cacheline_internodealigned_in_smp;#define ZONE_PADDING(name)      struct zone_padding name;#else#define ZONE_PADDING(name)#endif

内核还用了____cacheline_internodealigned_in_smp,来实现最优的高速缓存行对其方式.

该宏定义在include/linux/cache.h

#if !defined(____cacheline_internodealigned_in_smp)#if defined(CONFIG_SMP)#define ____cacheline_internodealigned_in_smp \__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))#else#define ____cacheline_internodealigned_in_smp#endif
#endif

4.3 水印watermark[NR_WMARK]与kswapd内核线程


Zone的管理调度的一些参数watermarks水印, 水存量很小(MIN)进水量,水存量达到一个标准(LOW)减小进水量,当快要满(HIGH)的时候,可能就关闭了进水口

WMARK_LOW, WMARK_LOW, WMARK_HIGH就是这个标准

enum zone_watermarks
{WMARK_MIN,WMARK_LOW,WMARK_HIGH,NR_WMARK
};#define min_wmark_pages(z) (z->watermark[WMARK_MIN])
#define low_wmark_pages(z) (z->watermark[WMARK_LOW])
#define high_wmark_pages(z) (z->watermark[WMARK_HIGH])

在linux-2.4中, zone结构中使用如下方式表示水印, 参照include/linux/mmzone.h?v=2.4.37, line 171

typedef struct zone_watermarks_s
{unsigned long min, low, high;
} zone_watermarks_t;typedef struct zone_struct {zone_watermarks_t       watermarks[MAX_NR_ZONES];

在Linux-2.6.x中标准是直接通过成员pages_min, pages_low and pages_high定义在zone结构体中的, 参照include/linux/mmzone.h?v=2.6.24, line 214

当系统中可用内存很少的时候,系统进程kswapd被唤醒, 开始回收释放page, 水印这些参数(WMARK_MIN, WMARK_LOW, WMARK_HIGH)影响着这个代码的行为

每个zone有三个水平标准:watermark[WMARK_MIN], watermark[WMARK_LOW], watermark[WMARK_HIGH],帮助确定zone中内存分配使用的压力状态

标准描述
watermark[WMARK_MIN]当空闲页面的数量达到page_min所标定的数量的时候, 说明页面数非常紧张, 分配页面的动作和kswapd线程同步运行.
WMARK_MIN所表示的page的数量值,是在内存初始化的过程中调用free_area_init_core中计算的。这个数值是根据zone中的page的数量除以一个>1的系数来确定的。通常是这样初始化的ZoneSizeInPages/12
watermark[WMARK_LOW]当空闲页面的数量达到WMARK_LOW所标定的数量的时候,说明页面刚开始紧张, 则kswapd线程将被唤醒,并开始释放回收页面
watermark[WMARK_HIGH]当空闲页面的数量达到page_high所标定的数量的时候, 说明内存页面数充足, 不需要回收, kswapd线程将重新休眠,通常这个数值是page_min的3倍

* 如果空闲页多于pages_high = watermark[WMARK_HIGH], 则说明内存页面充足, 内存域的状态是理想的.

  • 如果空闲页的数目低于pages_low = watermark[WMARK_LOW], 则说明内存页面开始紧张, 内核开始将页患处到硬盘.

  • 如果空闲页的数目低于pages_min = watermark[WMARK_MIN], 则内存页面非常紧张, 页回收工作的压力就比较大

4.3 内存域标志


内存管理域zone_t结构中的flags字段描述了内存域的当前状态

//  http://lxr.free-electrons.com/source/include/linux/mmzone.h#L475
struct zone
{/* zone flags, see below */unsigned long           flags;
}

它允许使用的标识用enum zone_flags标识, 该枚举标识定义在include/linux/mmzone.h?v4.7, line 525, 如下所示

enum zone_flags
{ZONE_RECLAIM_LOCKED,         /* prevents concurrent reclaim */ZONE_OOM_LOCKED,               /* zone is in OOM killer zonelist 内存域可被回收*/ZONE_CONGESTED,                 /* zone has many dirty pages backed by* a congested BDI*/ZONE_DIRTY,                           /* reclaim scanning has recently found* many dirty file pages at the tail* of the LRU.*/ZONE_WRITEBACK,                 /* reclaim scanning has recently found* many pages under writeback*/ZONE_FAIR_DEPLETED,           /* fair zone policy batch depleted */
};
flag标识描述
ZONE_RECLAIM_LOCKED防止并发回收, 在SMP上系统, 多个CPU可能试图并发的回收亿i个内存域. ZONE_RECLAIM_LCOKED标志可防止这种情况: 如果一个CPU在回收某个内存域, 则设置该标识. 这防止了其他CPU的尝试
ZONE_OOM_LOCKED用于某种不走运的情况: 如果进程消耗了大量的内存, 致使必要的操作都无法完成, 那么内核会使徒杀死消耗内存最多的进程, 以获取更多的空闲页, 该标志可以放置多个CPU同时进行这种操作
ZONE_CONGESTED标识当前区域中有很多脏页
ZONE_DIRTY用于标识最近的一次页面扫描中, LRU算法发现了很多脏的页面
ZONE_WRITEBACK最近的回收扫描发现有很多页在写回
ZONE_FAIR_DEPLETED公平区策略耗尽(没懂)

4.4 内存域统计信息vm_stat


内存域struct zone的vm_stat维护了大量有关该内存域的统计信息. 由于其中维护的大部分信息曲面没有多大意义

//  http://lxr.free-electrons.com/source/include/linux/mmzone.h#L522
struct zone
{atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
}

vm_stat的统计信息由enum zone_stat_item枚举变量标识, 定义在include/linux/mmzone.h?v=4.7, line 110

enum zone_stat_item
{/* First 128 byte cacheline (assuming 64 bit words) */NR_FREE_PAGES,NR_ALLOC_BATCH,NR_LRU_BASE,NR_INACTIVE_ANON = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */NR_ACTIVE_ANON,         /*  "     "     "   "       "         */NR_INACTIVE_FILE,       /*  "     "     "   "       "         */NR_ACTIVE_FILE,         /*  "     "     "   "       "         */NR_UNEVICTABLE,         /*  "     "     "   "       "         */NR_MLOCK,               /* mlock()ed pages found and moved off LRU */NR_ANON_PAGES,  /* Mapped anonymous pages */NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.only modified from process context */NR_FILE_PAGES,NR_FILE_DIRTY,NR_WRITEBACK,NR_SLAB_RECLAIMABLE,NR_SLAB_UNRECLAIMABLE,NR_PAGETABLE,           /* used for pagetables */NR_KERNEL_STACK,/* Second 128 byte cacheline */NR_UNSTABLE_NFS,        /* NFS unstable pages */NR_BOUNCE,NR_VMSCAN_WRITE,NR_VMSCAN_IMMEDIATE,    /* Prioritise for reclaim when writeback ends */NR_WRITEBACK_TEMP,      /* Writeback using temporary buffers */NR_ISOLATED_ANON,       /* Temporary isolated pages from anon lru */NR_ISOLATED_FILE,       /* Temporary isolated pages from file lru */NR_SHMEM,               /* shmem pages (included tmpfs/GEM pages) */NR_DIRTIED,             /* page dirtyings since bootup */NR_WRITTEN,             /* page writings since bootup */NR_PAGES_SCANNED,       /* pages scanned since last reclaim */
#ifdef CONFIG_NUMANUMA_HIT,               /* allocated in intended node */NUMA_MISS,              /* allocated in non intended node */NUMA_FOREIGN,           /* was intended here, hit elsewhere */NUMA_INTERLEAVE_HIT,    /* interleaver preferred this zone */NUMA_LOCAL,             /* allocation from local node */NUMA_OTHER,             /* allocation from other node */
#endifWORKINGSET_REFAULT,WORKINGSET_ACTIVATE,WORKINGSET_NODERECLAIM,NR_ANON_TRANSPARENT_HUGEPAGES,NR_FREE_CMA_PAGES,NR_VM_ZONE_STAT_ITEMS
};

内核提供了很多方式来获取当前内存域的状态信息, 这些函数大多定义在include/linux/vmstat.h?v=4.7

4.5 Zone等待队列表(zone wait queue table)


struct zone中实现了一个等待队列, 可用于等待某一页的进程, 内核将进程排成一个列队, 等待某些条件. 在条件变成真时, 内核会通知进程恢复工作.

struct zone
{wait_queue_head_t       *wait_table;unsigned long               wait_table_hash_nr_entries;unsigned long               wait_table_bits;
}
字段描述
wait_table待一个page释放的等待队列哈希表。它会被wait_on_page(),unlock_page()函数使用. 用哈希表,而不用一个等待队列的原因,防止进程长期等待资源
wait_table_hash_nr_entries哈希表中的等待队列的数量
wait_table_bits等待队列散列表数组大小, wait_table_size == (1 << wait_table_bits)

当对一个page做I/O操作的时候,I/O操作需要被锁住,防止不正确的数据被访问。进程在访问page前,wait_on_page_locked函数,使进程加入一个等待队列

访问完成后,UnlockPage函数解锁其他进程对page的访问。其他正在等待队列中的进程被唤醒。每个page都可以有一个等待队列,但是太多的分离的等待队列使得花费太多的内存访问周期。替代的解决方法,就是将所有的队列放在struct zone数据结构中

也可以有一种可能,就是struct zone中只有一个队列,但是这就意味着,当一个page unlock的时候,访问这个zone里内存page的所有休眠的进程将都被唤醒,这样就会出现拥堵(thundering herd)的问题。建立一个哈希表管理多个等待队列,能解决这个问题,zone->wait_table就是这个哈希表。哈希表的方法可能还是会造成一些进程不必要的唤醒。但是这种事情发生的机率不是很频繁的。下面这个图就是进程及等待队列的运行关系:

等待队列的哈希表的分配和建立在free_area_init_core函数中进行。哈希表的表项的数量在wait_table_size() 函数中计算,并且保持在zone->wait_table_size成员中。最大4096个等待队列。最小是NoPages / PAGES_PER_WAITQUEUE的2次方,NoPages是zone管理的page的数量,PAGES_PER_WAITQUEUE被定义256

zone->wait_table_bits用于计算:根据page 地址得到需要使用的等待队列在哈希表中的索引的算法因子. page_waitqueue()函数负责返回zone中page所对应等待队列。它用一个基于struct page虚拟地址的简单的乘法哈希算法来确定等待队列的.

page_waitqueue()函数用GOLDEN_RATIO_PRIME的地址和“右移zone→wait_table_bits一个索引值”的一个乘积来确定等待队列在哈希表中的索引的。

Zone的初始化, 在kernel page table通过paging_init()函数完全建立起z来以后,zone被初始化。下面章节将描述这个。当然不同的体系结构这个过程肯定也是不一样的,但它们的目的却是相同的:确定什么参数需要传递给free_area_init()函数(对于UMA体系结构)或者free_area_init_node()函数(对于NUMA体系结构)。这里省略掉NUMA体系结构的说明。
free_area_init()函数的参数:
unsigned long *zones_sizes: 系统中每个zone所管理的page的数量的数组。这个时候,还没能确定zone中那些page是可以分配使用的(free)。这个信息知道boot memory allocator完成之前还无法知道。
来源: http://www.uml.org.cn/embeded/201208071.asp

4.6 冷热页与Per-CPU上的页面高速缓存


内核经常请求和释放单个页框. 为了提升性能, 每个内存管理区都定义了一个每CPU(Per-CPU)的页面高速缓存. 所有”每CPU高速缓存”包含一些预先分配的页框, 他们被定义满足本地CPU发出的单一内存请求.

struct zone的pageset成员用于实现冷热分配器(hot-n-cold allocator)

struct zone
{struct per_cpu_pageset __percpu *pageset;
};

内核说页面是热的, 意味着页面已经加载到CPU的高速缓存, 与在内存中的页相比, 其数据访问速度更快. 相反, 冷页则不再高速缓存中. 在多处理器系统上每个CPU都有一个或者多个告诉缓存. 各个CPU的管理必须是独立的.

尽管内存域可能属于一个特定的NUMA结点, 因而关联到某个特定的CPU。 但其他CPU的告诉缓存仍然可以包含该内存域中的页面. 最终的效果是, 每个处理器都可以访问系统中的所有页, 尽管速度不同. 因而, 特定于内存域的数据结构不仅要考虑到所属NUMA结点相关的CPU, 还必须照顾到系统中其他的CPU.

pageset是一个指针, 其容量与系统能够容纳的CPU的数目的最大值相同.

数组元素类型为per_cpu_pageset, 定义在include/linux/mmzone.h?v4.7, line 254, 如下所示

struct per_cpu_pageset {struct per_cpu_pages pcp;
#ifdef CONFIG_NUMAs8 expire;
#endif
#ifdef CONFIG_SMPs8 stat_threshold;s8 vm_stat_diff[NR_VM_ZONE_STAT_ITEMS];
#endif
};

该结构由一个per_cpu_pages pcp变量组成, 该数据结构定义如下, 位于include/linux/mmzone.h?v4.7, line 245

struct per_cpu_pages {int count;              /* number of pages in the list 列表中的页数  */int high;               /* high watermark, emptying needed 页数上限水印, 在需要的情况清空列表  */int batch;              /* chunk size for buddy add/remove,  添加/删除多页块的时候, 块的大小  *//* Lists of pages, one per migrate type stored on the pcp-lists 页的链表*/struct list_head lists[MIGRATE_PCPTYPES];
};
字段描述
count记录了与该列表相关的页的数目
high是一个水印. 如果count的值超过了high, 则表明列表中的页太多了
batch如果可能, CPU的高速缓存不是用单个页来填充的, 而是欧诺个多个页组成的块, batch作为每次添加/删除页时多个页组成的块大小的一个参考值
list一个双链表, 保存了当前CPU的冷页或热页, 可使用内核的标准方法处理

在内核中只有一个子系统会积极的尝试为任何对象维护per-cpu上的list链表, 这个子系统就是slab分配器.

  • struct per_cpu_pageset具有一个字段, 该字段

  • struct per_cpu_pages则维护了链表中目前已有的一系列页面, 高极值和低极值决定了何时填充该集合或者释放一批页面, 变量决定了一个块中应该分配多少个页面, 并最后决定在页面前的实际链表中分配多少各页面

4.7 内存域的第一个页帧zone_start_pfn


struct zone中通过zone_start_pfn成员标记了内存管理区的页面地址.

然后内核也通过一些全局变量标记了物理内存所在页面的偏移, 这些变量定义在mm/nobootmem.c?v4.7, line 31

unsigned long max_low_pfn;
unsigned long min_low_pfn;
unsigned long max_pfn;
unsigned long long max_possible_pfn;

PFN是物理内存以Page为单位的偏移量

变量描述
max_low_pfnx86中,max_low_pfn变量是由find_max_low_pfn函数计算并且初始化的,它被初始化成ZONE_NORMAL的最后一个page的位置。这个位置是kernel直接访问的物理内存, 也是关系到kernel/userspace通过“PAGE_OFFSET宏”把线性地址内存空间分开的内存地址位置
min_low_pfn系统可用的第一个pfn是min_low_pfn变量, 开始与_end标号的后面, 也就是kernel结束的地方.在文件mm/bootmem.c中对这个变量作初始化
max_pfn系统可用的最后一个PFN是max_pfn变量, 这个变量的初始化完全依赖与硬件的体系结构.
max_possible_pfn

x86的系统中, find_max_pfn函数通过读取e820表获得最高的page frame的数值, 同样在文件mm/bootmem.c中对这个变量作初始化。e820表是由BIOS创建的

This is the physical memory directly accessible by the kernel and is related to the kernel/userspace split in the linear address space marked by PAGE OFFSET.

我理解为这段地址kernel可以直接访问,可以通过PAGE_OFFSET宏直接将kernel所用的虚拟地址转换成物理地址的区段。在文件mm/bootmem.c中对这个变量作初始化。在内存比较小的系统中max_pfn和max_low_pfn的值相同
min_low_pfn, max_pfn和max_low_pfn这3个值,也要用于对高端内存(high memory)的起止位置的计算。在arch/i386/mm/init.c文件中会对类似的highstart_pfn和highend_pfn变量作初始化。这些变量用于对高端内存页面的分配。后面将描述。

5 管理区表zone_table与管理区节点的映射


内核在初始化内存管理区时, 首先建立管理区表zone_table. 参见mm/page_alloc.c?v=2.4.37, line 38

/*** The zone_table array is used to look up the address of the* struct zone corresponding to a given zone number (ZONE_DMA,* ZONE_NORMAL, or ZONE_HIGHMEM).*/
zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
EXPORT_SYMBOL(zone_table);

MAX_NR_ZONES是一个节点中所能包容纳的管理区的最大数, 如3个, 定义在include/linux/mmzone.h?v=2.4.37, line 25, 与zone区域的类型(ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM)定义在一起. 当然这时候我们这些标识都是通过宏的方式来实现的, 而不是如今的枚举类型

MAX_NR_NODES是可以存在的节点的最大数.

函数EXPORT_SYMBOL使得内核的变量或者函数可以被载入的模块(比如我们的驱动模块)所访问.

该表处理起来就像一个多维数组, 在函数free_area_init_core中, 一个节点的所有页面都会被初始化.

6 zonelist内存域存储层次


6.1 内存域之间的层级结构


当前结点与系统中其他结点的内存域之前存在一种等级次序

我们考虑一个例子, 其中内核想要分配高端内存.

  1. 它首先企图在当前结点的高端内存域找到一个大小适当的空闲段. 如果失败, 则查看该结点的普通内存域. 如果还失败, 则试图在该结点的DMA内存域执行分配.

  2. 如果在3个本地内存域都无法找到空闲内存, 则查看其他结点. 在这种情况下, 备
    选结点应该尽可能靠近主结点, 以最小化由于访问非本地内存引起的性能损失.

内核定义了内存的一个层次结构, 首先试图分配”廉价的”内存. 如果失败, 则根据访问速度和容量, 逐渐尝试分配”更昂贵的”内存.

高端内存是最廉价的, 因为内核没有任何部份依赖于从该内存域分配的内存. 如果高端内存域用尽, 对内核没有任何副作用, 这也是优先分配高端内存的原因.

其次是普通内存域, 这种情况有所不同. 许多内核数据结构必须保存在该内存域, 而不能放置到高端内存域.

因此如果普通内存完全用尽, 那么内核会面临紧急情况. 所以只要高端内存域的内存没有用尽, 都不会从普通内存域分配内存.

最昂贵的是DMA内存域, 因为它用于外设和系统之间的数据传输. 因此从该内存域分配内存是最后一招.

6.2 zonelist结构


内核还针对当前内存结点的备选结点, 定义了一个等级次序. 这有助于在当前结点所有内存域的内存都用尽时, 确定一个备选结点

内核使用pg_data_t中的zonelist数组, 来表示所描述的层次结构.

typedef struct pglist_data {struct zonelist node_zonelists[MAX_ZONELISTS];/*  ......  */
}pg_data_t;

关于该结构zonelist的所有相关信息定义include/linux/mmzone.h?v=4.7, line 568, 我们下面慢慢来讲.

node_zonelists数组对每种可能的内存域类型, 都配置了一个独立的数组项.

该数组项的大小MAX_ZONELISTS用一个匿名的枚举常量定义, 定义在include/linux/mmzone.h?v=4.7, line 571

enum
{ZONELIST_FALLBACK,      /* zonelist with fallback */
#ifdef CONFIG_NUMA/** The NUMA zonelists are doubled because we need zonelists that* restrict the allocations to a single node for __GFP_THISNODE.*/ZONELIST_NOFALLBACK,    /* zonelist without fallback (__GFP_THISNODE) */
#endifMAX_ZONELISTS
};

我们会发现在UMA结构下, 数组大小MAX_ZONELISTS = 1, 因为只有一个内存结点, zonelist中只会存储一个ZONELIST_FALLBACK类型的结构, 但是NUMA下需要多余的ZONELIST_NOFALLBACK用以表示当前结点的信息

pg_data_t->node_zonelists数组项用struct zonelis结构体定义, 该结构包含了类型为struct zoneref的一个备用列表由于该备用列表必须包括所有结点的所有内存域,因此由MAX_NUMNODES * MAX_NZ_ZONES项组成,外加一个用于标记列表结束的空指针

struct zonelist结构的定义在include/linux/mmzone.h?v=4.7, line 606

/** One allocation request operates on a zonelist. A zonelist* is a list of zones, the first one is the 'goal' of the* allocation, the other zones are fallback zones, in decreasing* priority.** To speed the reading of the zonelist, the zonerefs contain the zone index* of the entry being read. Helper functions to access information given* a struct zoneref are** zonelist_zone()      - Return the struct zone * for an entry in _zonerefs* zonelist_zone_idx()  - Return the index of the zone for an entry* zonelist_node_idx()  - Return the index of the node for an entry*/
struct zonelist {struct zoneref _zonerefs[MAX_ZONES_PER_ZONELIST + 1];
};

而struct zoneref结构的定义如下include/linux/mmzone.h?v=4.7, line 583

/** This struct contains information about a zone in a zonelist. It is stored* here to avoid dereferences into large structures and lookups of tables*/
struct zoneref {struct zone *zone;      /* Pointer to actual zone */int zone_idx;       /* zone_idx(zoneref->zone) */
};

6.3 内存域的排列方式


那么我们内核是如何组织在zonelist中组织内存域的呢?

NUMA系统中存在多个节点, 每个节点对应一个struct pglist_data结构, 每个结点中可以包含多个zone, 如: ZONE_DMA, ZONE_NORMAL, 这样就产生几种排列顺序, 以2个节点2个zone为例(zone从高到低排列, ZONE_DMA0表示节点0的ZONE_DMA,其它类似).

  • Legacy方式, 每个节点只排列自己的zone;

Legacy方式

  • Node方式, 按节点顺序依次排列,先排列本地节点的所有zone,再排列其它节点的所有zone。

Node方式

  • Zone方式, 按zone类型从高到低依次排列各节点的同相类型zone

Zone方式

可通过启动参数”numa_zonelist_order”来配置zonelist order,内核定义了3种配置, 这些顺序定义在mm/page_alloc.c?v=4.7, line 4551

// http://lxr.free-electrons.com/source/mm/page_alloc.c?v=4.7#L4551
#define ZONELIST_ORDER_DEFAULT  0 /* 智能选择Node或Zone方式 */#define ZONELIST_ORDER_NODE     1 /* 对应Node方式 */#define ZONELIST_ORDER_ZONE     2 /* 对应Zone方式 */

注意

在非NUMA系统中(比如UMA), 由于只有一个内存结点, 因此ZONELIST_ORDER_ZONE和ZONELIST_ORDER_NODE选项会配置相同的内存域排列方式, 因此, 只有NUMA可以配置这几个参数

全局的current_zonelist_order变量标识了系统中的当前使用的内存域排列方式, 默认配置为ZONELIST_ORDER_DEFAULT, 参见mm/page_alloc.c?v=4.7, line 4564

//  http://lxr.free-electrons.com/source/mm/page_alloc.c?v=4.7#L4564
/* zonelist order in the kernel.* set_zonelist_order() will set this to NODE or ZONE.*/
static int current_zonelist_order = ZONELIST_ORDER_DEFAULT;
static char zonelist_order_name[3][8] = {"Default", "Node", "Zone"};

而zonelist_order_name方式分别对应了Legacy方式, Node方式和Zone方式. 其zonelist_order_name[current_zonelist_order]就标识了当前系统中所使用的内存域排列方式的名称”Default”, “Node”, “Zone”.

zonelist_order_name宏排列方式描述
ZONELIST_ORDER_DEFAULTDefault由系统智能选择Node或Zone方式
ZONELIST_ORDER_NODENodeNode方式按节点顺序依次排列,先排列本地节点的所有zone,再排列其它节点的所有zone
ZONELIST_ORDER_ZONEZoneZone方式按zone类型从高到低依次排列各节点的同相类型zone

内核就通过通过set_zonelist_order函数设置当前系统的内存域排列方式current_zonelist_order, 其定义依据系统的NUMA结构还是UMA结构有很大的不同. 该函数定义在mm/page_alloc.c?v=4.7, line 4571

6.4 build_all_zonelists初始化内存节点


内核通过build_all_zonelists初始化了内存结点的zonelists域

  • 首先内核通过set_zonelist_order函数设置了zonelist_order,如下所示, 参见mm/page_alloc.c?v=4.7, line 5031

  • 建立备用层次结构的任务委托给build_zonelists, 该函数为每个NUMA结点都创建了相应的数据结构. 它需要指向相关的pg_data_t实例的指针作为参数

7 总结


在linux中,内核也不是对所有物理内存都一视同仁,内核而是把页分为不同的区, 使用区来对具有相似特性的页进行分组.

Linux必须处理如下两种硬件存在缺陷而引起的内存寻址问题:

  1. 一些硬件只能用某些特定的内存地址来执行DMA

  2. 一些体系结构其内存的物理寻址范围比虚拟寻址范围大的多。这样,就有一些内存不能永久地映射在内核空间上。

为了解决这些制约条件,Linux使用了三种区:

  1. ZONE_DMA : 这个区包含的页用来执行DMA操作。

  2. ZONE_NOMAL : 这个区包含的都是能正常映射的页。

  3. ZONE_HIGHEM : 这个区包”高端内存”,其中的页能不永久地映射到内核地址空间

而为了兼容一些设备的热插拔支持以及内存碎片化的处理, 内核也引入一些逻辑上的内存区.

  1. ZONE_MOVABLE : 内核定义了一个伪内存域ZONE_MOVABLE, 在防止物理内存碎片的机制memory migration中需要使用该内存域. 供防止物理内存碎片的极致使用

  2. ZONE_DEVICE : 为支持热插拔设备而分配的Non Volatile Memory非易失性内存

区的实际使用与体系结构是相关的。linux把系统的内存结点划分区, 一个区包含了若干个内存页面, 形成不同的内存池,这样就可以根据用途进行分配了

需要说明的是,区的划分没有任何物理意义, 只不过是内核为了管理页而采取的一种逻辑上的分组. 尽管某些分配可能需要从特定的区中获得页, 但这并不是说, 某种用途的内存一定要从对应的区来获取,如果这种可供分配的资源不够用了,内核就会占用其他可用去的内存.

下表给出每个区及其在X86上所占的列表

每个区及其在X86上所占的列表

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 2006年我的常用工具列表

    数据库管理:PLSQL Developer:oracle 开发者必备工具Toad for Oracle 9.0: oracle dba必备工具Navicat MySQL:操作mysql 很简单的工具 系统管理:Xmanager Enterprise:登录aix,linux x window的工具SecureCRT 5.2:支持ssh, telnet等;SecureFX 4.0:支持sftp,ftp等;UltraVN…...

    2024/4/12 12:02:58
  2. phpexcel出现无法访问此网站,ERR_INVALID_RESPONSE

    最近在做phpexcel导出的时候,发现不能下载文件首先查看是否没有加 header都加了的,还是没法导出。 google谈起原因是之后发现在导出excel之前要清空缓存区,于是在调用save("php://output")之前调用ob_end_clean()ob_end_clean(); $objWriter->save(php://output…...

    2024/4/18 17:02:35
  3. 数据库课程设计 ——酒店管理系统

    一、 需求分析 1.软件需求 (1)酒店管理系统用于满足酒店工作人员和管理人员的需求。 (2)酒店管理人员和工作人员可以为酒店房间加入入住和退房记录,并生成相应的报表用于查阅,确认和保存,酒店工作人员可以浏览、查询、统计、添加酒店房间的入住离开信息。管理员可以查询…...

    2024/5/6 11:08:38
  4. windows系统打开火狐浏览器提示“无法加载您的firefox配置文件。它可能已经丢失,或是无法访问。” 解决办法

    Windows系统自带IE浏览器,可是有很多用户使用不习惯,选择下载第三方浏览器,比如:火狐浏览器、谷歌浏览器、360浏览器等。最近有朋友在重新安装火狐浏览器后发现打不开,并提示“无法加载你的firefox配置文件 。它可能已经丢失,或是无法访问”的故障,就算是重装也没有用,…...

    2024/4/29 20:17:56
  5. dwg文件怎么打开?dwg文件用什么打开?

    dwg文件怎么打开dwg文件打开方法汇总:第一步:安装AutoCAD,专业的CAD绘图软件,因为该软件设计出来的图纸保存的文件格式就是dwg文件。第二步:下载安装dwg文件浏览器由于不少朋友只是查看图纸,本身对CAD并不了解,而AutoCAD绘图软件输入3D大型制图软件,如果仅仅只是查看图…...

    2024/4/18 10:15:53
  6. 【LINUNX】常用的Nginx命令

    /usr/local/webserver/nginx/sbin/nginx # 启动Nginx /usr/local/webserver/nginx/sbin/nginx -t # 检查配置文件nginx.conf的正确性 /usr/local/webserver/nginx/sbin/nginx -s reload # 重新载入配置文件 /usr/local/webs…...

    2024/4/20 8:14:36
  7. linux内存管理概述

    linux内存管理建立在基本的分页机制基础上,在linux内核中RAM的某些部分将会永久的分配给内核,并用来存放内核代码以及静态内核数据结构。RAM的其余部分称为动态内存,这不仅是进程所需的宝贵资源,也是内核本身所需的宝贵资源。实际上,整个系统的性能取决于如何有效地管理动…...

    2024/4/24 3:33:02
  8. 关于Google的BlogSpot Blog不能访问

    关于Google的BlogSpot blog不能访问连续好几天了,blogspot都不能访问,这次的原因肯定不是因为地震震断海底光缆了,我想大家都清楚作为一介布衣,我是非常的气愤!我对政治不关心,就算有什么反动信息我也没有兴趣去看的!!此地无银三百两!幸好找到一个BlogSpot 登录器,输…...

    2024/5/4 1:56:52
  9. 浏览器无法访问网页、播放视频、上传下载附件等问题原因即解决

    前言我们上网浏览各种网站,使用浏览器的时候可能会遇到一些问题,为了解决这些问题而在网上四处的找答案,于是,为了方便大家,我总结了一些的问题原因及解决方法,可能不太全,以后添加。一、浏览器无法访问网页1.浏览器的版本太老 (浏览器的版本可能导致某些网站的网页无…...

    2024/4/25 16:43:51
  10. Centos7安装Nginx教程

    Nginx下载 1.下载nginx nginx官方下载地址Windows要使用nginx的话,只需要下载解压就可以。 2.安装nginx 将nginx.tar.gz传到centos上,默认会传到/root目录下 输入下面指令,检查并自动安装必备的运行库 yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-dev…...

    2024/4/12 12:03:35
  11. dwg文件怎么打开呢?dwg是啥呢?

    学习过绘图AUTO CAD的朋友对dwg文件再熟悉不过了,dwg是二维或三维图形,一般的建筑图纸通信图纸电气图纸都是用cad绘制的,但对于没学习过CAD绘图的朋友对*.dwg文件都是一脸茫然,今天刚好有量产网网友问了编辑dwg文件怎么打开,编辑这里介绍下常用的打开dwg文件方法汇总,其实…...

    2024/4/19 12:29:27
  12. 无法安装ADT(无法访问https://dl-ssl.google.com/android/eclipse/) 的解决方法

    最近在Ubuntu12.04下搭建Android开发环境时发现无法安装Eclipse插件ADT,安装过程中出现如下提示:Unable to connect to repository https://dl-ssl.google.com/android/eclipse/content.xml Unable to connect to repository https://dl-ssl.google.com/android/eclipse/cont…...

    2024/4/18 12:39:07
  13. Linux内存管理(下)

    Linux内存管理(下)物理内存管理(页管理)Linux内核管理物理内存是通过分页机制实现的,它将整个内存划分成无数4k(在i386体系结构中)大小页,从而分配和回收内存的基本单位便是内存页了。利用分页管理有助于灵活分配内存地址,因为分配时不必要求必须有大块的连续内存[1],系统…...

    2024/5/3 23:10:17
  14. C#餐厅管理系统1--ER图

    C#餐厅管理系统6--呼叫管理员! 地址:点击打开链接 C#餐厅管理系统5--餐桌和职员 地址:点击打开链接 C#餐厅管理系统4--增删改查! 地址:点击打开链接 C#餐厅管理系统3--MAIN窗口 地址:点击打开链接 C#餐厅管理系统2--数据连接…...

    2024/5/4 7:31:13
  15. 用软件轻松实现DWG批量转PDF

    DWG:AotuCAD的标准格式,只在AotuCAD中使用,交流极不方便。PDF:PDF是一种开放式电子文件格式(符合美国Adobe公司Acrobat 之PDF标准),不论使用哪一种计算机平台或应用软件编辑的文件,几乎都可转换成PDF格式互通使用。PDF是目前使用最广的格式。随着对外交流的增多,PDF文…...

    2024/5/4 7:35:38
  16. 发布Google Play的应用facebook登录异常

    问题: facebbook后台配置了debug和release的签名,然后发布发布google play之后,下载下来的应用登录facebook会报签名错误,原因是google play重新签名了. 解决: 把google play的签名加到facebook后台就行了 1.在google play的版本管理-应用签名 下载签名证书deployment_cert.der…...

    2024/4/12 12:03:59
  17. 面试题总结之windows/linux内存管理

    前言请说说你对windows/linux内存管理的认识解答内存管理的必要性出现在早期的计算机系统当中,程序是直接运行在物理内存中,每一个程序都能直接访问物理地址。如果这个系统只运行一个程序的话,并且这个程序所需的内存不要超过该机器的物理内存就不会出现问题。但是如今的系统…...

    2024/4/12 12:03:29
  18. 最简单的docker教程:在docker里运行nginx服务器

    命令行docker search nginx搜索名为nginx的docker image,返回结果的第一个,github上有10293个star,这就是我们想要搜索的结果:使用命令docker pull把这个镜像拖下来: docker pull nginx然后以detach模式运行这个镜像: docker run -d --name jerry-nginx nginxdocker run的…...

    2024/4/16 21:14:01
  19. 37、购物系统需求分析

    学习目标:1、通过一个简单的项目示例复习本阶段的知识2、能独立分析项目,了解项目的一般建设流程学习过程:jsp和servlet的基本知识点就讲完了,但是我们需要做一个完整的项目巩固一下才行,否则还是不会应用这些技术的,接下来几天我们以前做一个网上购物系统。这里先给出这…...

    2024/5/3 23:34:00
  20. 深入理解Linux内存管理机制

    深入理解Linux内存管理机制(一) 淘宝核心系统团队博客深入理解Linux内存管理机制(一)通过本文,您即可以: 1. 存储器硬件结构; 2.分段以及对应的组织方式; 3.分页以及对应的组织方式。 注1:本文以Linux内核2.6.32.59本版为例,其对应的代码可以在http://www.kernel.org…...

    2024/5/4 12:32:03

最新文章

  1. 群发邮件软件哪个好

    选择一个好的群发邮件软件取决于您的具体需求&#xff0c;如预算、邮件量、自动化需求、分析深度以及是否需要集成其他营销工具等。以下是一些评价较高且功能强大的群发邮件软件&#xff0c;您可以根据自身情况选择&#xff1a; 易邮件群发大师&#xff1a;一款传统使用最广泛的…...

    2024/5/6 13:18:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/6 9:38:23
  3. 腾讯云轻量服务器流量不够用了会怎么样?

    腾讯云轻量应用服务器是限制月流量的&#xff0c;如果当月流量不够用了&#xff0c;流量超额了怎么办&#xff1f;流量超额后&#xff0c;需要另外支付流量费&#xff0c;如果你的腾讯云账号余额&#xff0c;就会自动扣除对应的流量费&#xff0c;如果余额不足&#xff0c;轻量…...

    2024/5/1 13:01:36
  4. 图像处理相关知识 —— 椒盐噪声

    椒盐噪声是一种常见的图像噪声类型&#xff0c;它会在图像中随机地添加黑色&#xff08;椒&#xff09;和白色&#xff08;盐&#xff09;的像素点&#xff0c;使图像的质量降低。这种噪声模拟了在图像传感器中可能遇到的问题&#xff0c;例如损坏的像素或传输过程中的干扰。 椒…...

    2024/5/5 8:37:08
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/6 9:21:00
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57