Linux 메모리 관리 관련 기능: 1. 커널 모드에서 메모리 할당에 사용되는 kmalloc(), 일반적으로 소프트웨어에만 존재하는 더 큰 시퀀스에 사용됩니다(해당 하드웨어 의미 없음). 버퍼는 메모리를 할당합니다. . alloc_page() 및 alloc_pages() 함수는 커널 공간에 할당될 수 있습니다. 4. __get_free_pages() 함수 시리즈는 하나 이상의 페이지의 가상 주소를 반환합니다.
이 튜토리얼의 운영 환경: linux7.3 시스템, Dell G3 컴퓨터.
이 문서에서는 Linux의 기본 메모리 할당 메커니즘을 더 잘 이해할 수 있도록 Linux 커널의 몇 가지 일반적인 메모리 할당 기능과 그 유사점 및 차이점을 설명합니다.
1.kmalloc()
kmalloc() 함수는 일반적인 malloc() 함수와 유사하며 전자는 커널 모드에서 메모리 할당에 사용되고 후자는 사용자 모드에 사용됩니다.
kmalloc() 함수는 물리적 메모리에 연속 저장 공간을 할당하며, malloc() 함수와 마찬가지로 메모리가 충분하면 내부의 원본 데이터를 지우지 않으며 할당 속도가 매우 빠릅니다. 프로토타입은 다음과 같습니다:
static inline void *kmalloc(size_t size, gfp_t flags); /*返回的是虚拟地址*/
- size: 할당할 메모리 크기입니다. Linux 메모리 관리 메커니즘으로 인해 메모리는 페이지 크기(일반적으로 32비트 시스템의 경우 4KB, 64비트 시스템의 경우 8KB)에 따라서만 할당될 수 있습니다. 이로 인해 몇 바이트만 필요할 때 시스템이 계속 반환됩니다. 메모리 한 페이지는 분명히 매우 낭비적입니다. 따라서 malloc과 달리 kmalloc의 처리 방법은 다음과 같습니다. 커널은 먼저 다양한 크기(32B, 64B, 128B,..., 128KB)의 일련의 메모리 풀을 할당합니다. 메모리를 할당해야 할 경우 시스템은 더 큰 메모리 풀을 할당합니다. 크거나 같음 메모리가 필요한 가장 작은 메모리 풀을 제공합니다. 즉, kmalloc이 할당하는 메모리는 최소 32바이트, 최대 128KB이다. 128KB를 초과하는 경우 vmalloc()과 같은 다른 메모리 할당 함수를 샘플링해야 합니다.
-
flag: 이 매개변수는 함수의 동작을 제어하는 데 사용됩니다. 가장 일반적으로 사용되는 매개변수는 GFP_KERNEL입니다. 즉, 현재 할당된 메모리가 충분하지 않으면 시스템이 콘텐츠를 교환한 후 프로세스가 절전 모드로 전환됩니다. 하드 디스크에 버퍼를 추가하면 충분한 메모리가 확보됩니다. 그런 다음 프로세스를 깨우고 메모리를 할당합니다. 더 많은 플래그는 아래 그림을 참조하세요.
- GFP_KERNEL 플래그를 사용하여 메모리를 적용할 때 일시적으로 만족할 수 없으면 프로세스가 잠자기 상태로 페이지를 기다리게 되어 차단이 발생하므로 사용할 수 없습니다. 컨텍스트를 중단하거나 스핀 잠금을 유지하는 경우 GFP_KERNE이 메모리에 적용됩니다. 따라서 인터럽트 처리기, 태스크릿 및 커널 타이머와 같은 비프로세스 컨텍스트에서는 차단할 수 없습니다. 이 경우 드라이버는 GFP_ATOMIC 플래그를 사용하여 메모리를 적용해야 합니다. GFP_ATOMIC 플래그를 사용하여 메모리를 적용할 때 여유 페이지가 없으면 기다리지 않고 바로 반환됩니다.
- 위 표에 나열된 플래그 외에 다음도 포함됩니다:
- _ _GFP_DMA(DMA 가능 메모리 영역에 할당해야 함)
- _ _GFP_HIGHMEM(할당된 메모리가 하이엔드 메모리에 위치)
- _ _GFP_COLD (필수 오랫동안 접근하지 않은 페이지)
- _ _GFP_NOWARN (할당을 채울 수 없을 때 커널이 경고를 발행하는 것을 방지)
- _ _GFP_HIGH (높음) 우선 순위 요청, 긴급 사용을 위해 커널이 예약한 마지막 메모리 페이지를 얻을 수 있습니다 )
- _ _GFP_REPEAT (할당이 실패하면 최선을 다해 재시도하십시오)
- _ _GFP_NOFAIL (표시는 성공적인 적용만 허용하며 권장되지 않음)
- _ _GFP_NORETRY (응용이 실패하면 즉시 포기하세요)
- kmalloc()을 사용하여 메모리를 신청합니다.
kfree()
를 사용하여 해제해야 합니다. 이 함수의 사용법은 사용자 공간에서 free()와 유사합니다. .kfree()
释放,这个函数的用法和用户空间的 free()类似。
2、vmalloc()
vmalloc()
一般用在为只存在于软件中(没有对应的硬件意义)的较大的顺序缓冲区分配内存,当内存没有足够大的连续物理空间可以分配时,可以用该函数来分配虚拟地址连续但物理地址不连续的内存。由于需要建立新的页表,所以它的开销要远远大于kmalloc及后面将要讲到的__get_free_pages()
函数。且vmalloc()
不能用在原子上下文中,因为它的内部实现使用了标志为 GFP_KERNEL 的kmalloc()
vmalloc()
은 일반적으로 소프트웨어에만 존재하므로 사용됩니다(해당 하드웨어 의미가 없음). 더 큰 순차 버퍼는 메모리를 할당합니다. 메모리에 할당할 만큼 큰 연속 물리적 공간이 없는 경우 이 기능을 사용하여 연속적인 가상 주소와 비연속적인 물리적 주소로 메모리를 할당할 수 있습니다. 새로운 페이지 테이블을 생성해야 하기 때문에 그 오버헤드는 나중에 설명할 kmalloc 및 __get_free_pages()
함수보다 훨씬 큽니다. 그리고 vmalloc()
은 내부 구현이 GFP_KERNEL 플래그와 함께 kmalloc()
를 사용하기 때문에 원자적 컨텍스트에서 사용할 수 없습니다. 함수 프로토타입은 다음과 같습니다: 🎜void *vmalloc(unsigned long size); void vfree(const void *addr);
- 使用 vmalloc 函数的一个例子函数是
create_module()
系统调用,它利用 vmalloc()函数来获取被创建模块需要的内存空间。 - 内存分配是一项要求严格的任务,无论什么时候,都应该对返回值进行检测。
- 在驱动编程中可以使用
copy_from_user()
对内存进行使用。下面举一个使用vmalloc函数的示例:
static int xxx(...) { ... cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent); if(!cpuid_entries) goto out; if(copy_from_user(cpuid_entries, entries, cpuid->nent * sizeof(struct kvm_cpuid_entry))) goto out_free; for(i=0; i<cpuid->nent; i++){ vcpuid->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; ... vcpuid->arch.cpuid_entries[i].index = 0; } ... out_free: vfree(cpuid_entries); out: return r; }
3、页分配函数
在linux中,内存分配是以页为单位的,32位机中一页为4KB,64位机中,一页为8KB,但具体还有根据平台而定。
根据返回值类型的不同,页分配函数分为两类,一是返回物理页地址,二是返回虚拟地址。虚拟地址和物理地址起始相差一个固定的偏移量。
#define __pa(x) ((x) - PAGE_OFFSET) static inline unsigned long virt_to_phys(volatile void *address) { return __pa((void *)address); } #define __va(x) ((x) + PAGE_OFFSET) static inline void* phys_to_virt(unsigned long address) { return __va(address); }
根据返回页面数目分类,分为仅返回单页面的函数和返回多页面的函数。
3.1 alloc_page()和alloc_pages()函数
该函数定义在头文件/include/linux/gfp.h
中,它既可以在内核空间分配,也可以在用户空间分配,它返回分配的第一个页的描述符而非首地址,其原型为:
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) #define alloc_pages(gfp_mask, order) alloc_pages_node(numa_node_id(), gfp_mask, order) //分配连续2^order个页面 static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order) { if(unlikely(order >= MAX_ORDER)) return NULL; if(nid < 0) nid = numa_node_id(); return __alloc_pages(gfp_mask, order, noed_zonelist(nid, gfp_mask)); }
3.2 __get_free_pages()系列函数
它是kmalloc函数实现的基础,返回一个或多个页面的虚拟地址。该系列函数/宏包括 get_zeroed_page()
、_ _get_free_page()
和_ _get_free_pages()
。在使用时,其申请标志的值及含义与 kmalloc()
完全一样,最常用的是 GFP_KERNEL 和 GFP_ATOMIC。
/*分配多个页并返回分配内存的首地址,分配的页数为2^order,分配的页不清零。 order 允许的最大值是 10(即 1024 页)或者 11(即 2048 页),依赖于具体 的硬件平台。*/ unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) { struct page *page; page = alloc_pages(gfp_mask, order); if(!page) return 0; return (unsigned long)page_address(page); } #define __get_free_page(gfp_mask) __get_free_pages(gfp_mask, 0) /*该函数返回一个指向新页的指针并且将该页清零*/ unsigned long get_zeroed_page(unsigned int flags);
- 使用
_ _get_free_pages()
系列函数/宏申请的内存应使用free_page(addr)
或free_pages(addr, order)
函数释放:
#define __free_page(page) __free_pages((page), 0) #define free_page(addr) free_pages((addr), 0) void free_pages(unsigned long addr, unsigned int order) { if(addr != 0){ VM_BUG_ON(!virt_addr_valid((void*)addr)); __free_pages(virt_to_page((void *)addr), order); } } void __free_pages(struct page *page, unsigned int order) { if(put_page_testzero(page)){ if(order == 0) free_hot_page(page); else __free_pages_ok(page, order); } }
free_pages()函数是调用__free_pages()函数完成内存释放的。
4、slab缓存
- 当在驱动程序中,遇到反复分配、释放同一大小的内存块时(例如,inode、task_struct等),建议使用内存池技术(对象在前后两次被使用时均分配在同一块内存或同一类内存空间,且保留了基本的数据结构,这大大提高了效率)。在linux中,有一个叫做slab分配器的内存池管理技术,内存池使用的内存区叫做后备高速缓存。
- salb相关头文件在linux/slab.h中,在使用后备高速缓存前,需要创建一个
kmem_cache
的结构体。
4.1 创建slab缓存区
该函数创建一个slab缓存(后备高速缓冲区),它是一个可以驻留任意数目全部同样大小的后备缓存。其原型如下:
struct kmem_cache *kmem_cache_create(const char *name, size_t size, \ size_t align, unsigned long flags,\ void (*ctor)(void *, struct kmem_cache *, unsigned long),\ void (*dtor)(void *, struct kmem_cache *, unsigned ong)));
其中:
name:创建的缓存名;
size:可容纳的缓存块个数;
align:后备高速缓冲区中第一个内存块的偏移量(一般置为0);
flags:控制如何进行分配的位掩码,包括 SLAB_NO_REAP
(即使内存紧缺也不自动收缩这块缓存)、SLAB_HWCACHE_ALIGN
( 每 个 数 据 对 象 被 对 齐 到 一 个 缓 存 行 )、SLAB_CACHE_DMA
(要求数据对象在 DMA 内存区分配)等);
ctor:是可选的内存块对象构造函数(初始化函数);
dtor:是可选的内存对象块析构函数(释放函数)。
4.2 分配slab缓存函数
一旦创建完后备高速缓冲区后,就可以调用kmem_cache_alloc()
在缓存区分配一个内存块对象了,其原型如下:
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
cachep指向开始分配的后备高速缓存,flags与传给kmalloc函数的参数相同,一般为GFP_KERNEL。
4.3 释放slab缓存
该函数释放一个内存块对象:
void *kmem_cache_free(struct kmem_cache *cachep, void *objp);
4.4 销毁slab缓存
与kmem_cache_create
对应的是销毁函数,释放一个后备高速缓存:
int kmem_cache_destroy(struct kmem_cache *cachep);
它必须等待所有已经分配的内存块对象被释放后才能释放后备高速缓存区。
4.5 slab缓存使用举例
创建一个存放线程结构体(struct thread_info)的后备高速缓存,因为在linux中涉及频繁的线程创建与释放,如果使用__get_free_page()函数会造成内存的大量浪费,效率也不高。所以在linux内核的初始化阶段就创建了一个名为thread_info的后备高速缓存,代码如下:
/* 创建slab缓存 */ static struct kmem_cache *thread_info_cache; thread_info_cache = kmem_cache_create("thread_info", sizeof(struct thread_info), \ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); /* 分配slab缓存 */ struct thread_info *ti; ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL); /* 使用slab缓存 */ ... /* 释放slab缓存 */ kmem_cache_free(thread_info_cache, ti); kmem_cache_destroy(thread_info_cache);
5、内存池
在 Linux 内核中还包含对内存池的支持,内存池技术也是一种非常经典的用于分配大量小对象的后备缓存技术。
5.1 创建内存池
mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, \ mempool_free_t *free_fn, void *pool_data);
mempool_create()函数用于创建一个内存池,min_nr 参数是需要预分配对象的数目,alloc_fn 和 free_fn 是指向内存池机制提供的标准对象分配和回收函数的指针,其原型分别为:
typedef void *(mempool_alloc_t)(int gfp_mask, void *pool_data); typedef void (mempool_free_t)(void *element, void *pool_data);
pool_data 是分配和回收函数用到的指针,gfp_mask 是分配标记。只有当_ _GFP_WAIT
标记被指定时,分配函数才会休眠。
5.2 分配和回收对象
在内存池中分配和回收对象需由以下函数来完成:
void *mempool_alloc(mempool_t *pool, int gfp_mask); void mempool_free(void *element, mempool_t *pool);
mempool_alloc()用来分配对象,如果内存池分配器无法提供内存,那么就可以用预分配的池。
5.3 销毁内存池
void mempool_destroy(mempool_t *pool);
mempool_create()函数创建的内存池需由 mempool_destroy()来回收。
相关推荐:《Linux视频教程》
위 내용은 리눅스 메모리 관리와 관련된 여러 기능의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

Linux의 기본 구조에는 커널, 파일 시스템 및 쉘이 포함됩니다. 1) 커널 관리 하드웨어 리소스 및 UNAME-R을 사용하여 버전을보십시오. 2) Ext4 파일 시스템은 큰 파일과 로그를 지원하며 mkfs.ext4를 사용하여 생성됩니다. 3) Shell은 Bash와 같은 명령 줄 상호 작용을 제공하고 LS-L을 사용하는 파일을 나열합니다.

Linux 시스템 관리 및 유지 보수의 주요 단계에는 다음이 포함됩니다. 1) 파일 시스템 구조 및 사용자 관리와 같은 기본 지식을 마스터합니다. 2) 시스템 모니터링 및 리소스 관리를 수행하고 Top, HTOP 및 기타 도구를 사용하십시오. 3) 시스템 로그를 사용하여 문제를 해결하고 JournalCTL 및 기타 도구를 사용하십시오. 4) 자동 스크립트 및 작업 스케줄링을 작성하고 CRON 도구를 사용하십시오. 5) 보안 관리 및 보호 구현, iptables를 통해 방화벽을 구성합니다. 6) 성능 최적화 및 모범 사례를 수행하고 커널 매개 변수를 조정하며 좋은 습관을 개발하십시오.

시작시 init =/bin/bash 또는 단일 매개 변수를 추가하여 Linux 유지 관리 모드가 입력됩니다. 1. 유지 보수 모드를 입력하십시오 : 그루브 메뉴를 편집하고 시작 매개 변수를 추가하십시오. 2. 파일 시스템을 다시 마운트하여 읽고 쓰기 모드 : MOUNT-OREMOUNT, RW/. 3. 파일 시스템 수리 : FSCK/DEV/SDA1과 같은 FSCK 명령을 사용하십시오. 4. 데이터 손실을 피하기 위해 데이터를 백업하고주의해서 작동합니다.

이 기사에서는 데비안 시스템에서 Hadoop 데이터 처리 효율성을 향상시키는 방법에 대해 설명합니다. 최적화 전략에는 하드웨어 업그레이드, 운영 체제 매개 변수 조정, Hadoop 구성 수정 및 효율적인 알고리즘 및 도구 사용이 포함됩니다. 1. 하드웨어 리소스 강화는 모든 노드에 일관된 하드웨어 구성, 특히 CPU, 메모리 및 네트워크 장비 성능에주의를 기울일 수 있도록합니다. 전반적인 처리 속도를 향상시키기 위해서는 고성능 하드웨어 구성 요소를 선택하는 것이 필수적입니다. 2. 운영 체제 조정 파일 설명 자 및 네트워크 연결 : /etc/security/limits.conf 파일을 수정하여 파일 설명자의 상한을 늘리고 동시에 시스템에 의해 열 수 있습니다. JVM 매개 변수 조정 : Hadoop-env.sh 파일에서 조정

이 안내서는 데비안 시스템에서 syslog를 사용하는 방법을 배우도록 안내합니다. Syslog는 로깅 시스템 및 응용 프로그램 로그 메시지를위한 Linux 시스템의 핵심 서비스입니다. 관리자가 시스템 활동을 모니터링하고 분석하여 문제를 신속하게 식별하고 해결하는 데 도움이됩니다. 1. syslog에 대한 기본 지식 syslog의 핵심 기능에는 다음이 포함됩니다. 로그 메시지 중앙 수집 및 관리; 다중 로그 출력 형식 및 대상 위치 (예 : 파일 또는 네트워크) 지원; 실시간 로그보기 및 필터링 기능 제공. 2. Syslog 설치 및 구성 (RSYSLOG 사용) Debian 시스템은 기본적으로 RSYSLOG를 사용합니다. 다음 명령으로 설치할 수 있습니다 : sudoaptupdatesud

데비안 시스템에 적합한 Hadoop 버전을 선택할 때는 다음과 같은 주요 요소를 고려해야합니다. 1. 안정성 및 장기 지원 : 안정성과 보안을 추구하는 사용자의 경우 Debian11 (Bullseye)과 같은 데비안 안정 버전을 선택하는 것이 좋습니다. 이 버전은 완전히 테스트되었으며 최대 5 년의 지원주기가있어 시스템의 안정적인 작동을 보장 할 수 있습니다. 2. 패키지 업데이트 속도 : 최신 Hadoop 기능 및 기능을 사용해야하는 경우 Debian의 불안정한 버전 (SID)을 고려할 수 있습니다. 그러나 불안정한 버전에는 호환성 문제와 안정성 위험이있을 수 있습니다. 3. 커뮤니티 지원 및 자원 : 데비안은 풍부한 문서를 제공하고

이 기사에서는 Tigervnc를 사용하여 데비안 시스템에서 파일을 공유하는 방법에 대해 설명합니다. 먼저 tigervnc 서버를 설치 한 다음 구성해야합니다. 1. TigervNC 서버를 설치하고 터미널을 엽니 다. 소프트웨어 패키지 목록 업데이트 : sudoaptupdate tigervnc 서버를 설치하려면 : sudoaptinstalltigervnc-standalone-servertigervnc-common 2. VNC 서버 비밀번호를 설정하도록 tigervnc 서버 구성 : vncpasswd vnc 서버 : vncserver : 1-localhostno

데비안 메일 서버의 방화벽 구성은 서버 보안을 보장하는 데 중요한 단계입니다. 다음은 iptables 및 방화구 사용을 포함하여 일반적으로 사용되는 여러 방화벽 구성 방법입니다. iptables를 사용하여 iptables를 설치하도록 방화벽을 구성하십시오 (아직 설치되지 않은 경우) : sudoapt-getupdatesudoapt-getinstalliptablesview 현재 iptables 규칙 : sudoiptables-l configuration


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

WebStorm Mac 버전
유용한 JavaScript 개발 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기
