> 운영 및 유지보수 > 리눅스 운영 및 유지 관리 > Linux에서 메모리 통계 및 메모리 누수를 확인하는 방법

Linux에서 메모리 통계 및 메모리 누수를 확인하는 방법

巴扎黑
풀어 주다: 2017-08-10 11:43:52
원래의
1763명이 탐색했습니다.

[소개] 제품 개발 시 현재 시스템에서 소비하는 전체 메모리 양을 계산하여 제품에 필요한 전체 메모리 양을 정확하게 평가하여 적절한 메모리 칩과 크기를 선택하고 제품 비용을 절감할 수 있습니다. . 메모리 누수와 같은 문제가 발생하면 우리는 종종 무기력해집니다. 이 기사에서는 제품 개발 시 현재 시스템에서 소비하는 총 메모리에 대한 통계를 통해 제품 평가에 필요한 총 메모리를 정확하게 예측할 수 있습니다. 적절한 메모리 칩과 크기를 선택하고 제품 가격을 절감합니다. 메모리 누수 문제가 발생하면 우리는 무력한 경우가 많습니다. 이 기사에서는 시스템에서 소비하는 메모리 크기를 정확하게 평가하기 위해 프로세스 관련 파일을 분석합니다. 메모리 누수 문제를 해결하기 위한 위치 지정 방법도 제공할 수 있습니다.

Linux의 메모리 사용 원칙은 다음과 같습니다. 메모리가 충분하면 헛되이 사용하지 말고 메모리를 사용하여 일부 파일을 캐시하여 메모리가 부족할 때 프로세스 실행 속도를 높이세요. 캐시 메모리는 해당 메모리 재활용 전략을 통해 회수되어 프로세스에서 사용됩니다.

1. 전체 시스템 메모리 분석

proc 디렉터리에 있는 meminfo 파일에서 현재 시스템 메모리 사용량 요약을 확인할 수 있습니다. 사용 가능한 물리적 메모리 = memfree+buffers+cached. 커널은 캐시 및 버퍼링된 메모리가 쓰기 저장 메커니즘(pdflush 스레드)을 통해 백업 메모리에 다시 기록되어 프로세스 사용을 위해 관련 메모리를 해제하거나 명시적으로 캐시 메모리를 수동으로 해제합니다.

echo 3 > /proc/sys/vm/drop_caches
로그인 후 복사

아래 그림은 현재 시스템을 보여줍니다. HiSilicon 플랫폼의 메모리 전체 사용량을 보면 시스템이 29M의 메모리를 소비하는 것을 볼 수 있습니다. 이 메모리를 누가 소비하는지 계속해서 분석해 보겠습니다.

# cat /proc/meminfo
로그인 후 복사

MemTotal: 68956 kBMemFree: 18632 kB

  二、进程使用内存的统计

在32位操作系统中,每个进程拥有4G的虚拟内存空间,其中0~3GB是每个进程的私有用户空间,这个空间对系统中其他进程是不可见的。3~4GB是linux内核空间,由系统所有的进程以及内核所共享的。通过访问/proc/{pid}/下相关文件,可以了解每个线程虚拟内存空间的使用情况,从而了解每个线程所消耗内存的多少。

由于我们的产品都是使用多线程方式实现的,多个线程共享一个进程的用户态虚拟地址空间,虚拟地址空间包含若干区域,主要有如下几个区域:

1、当前执行文件的代码段,该代码段称为text段。

2、执行文件的数据段,主要存储执行文件用到的全局变量,静态变量。

3、存储全局变量和动态产生的数据的堆。

4、用于保存局部变量和实现函数调用的栈。

5、采用mmap方式映射到虚拟地址空间中的内存段

所以只需要查看任意一个线程的用户态虚拟地址空间分配即可知道属于同一进程的所有线程占用总内存的大小。可以通过查看/proc/{pid}/maps文件来获取相关的虚拟地址空间内容,下文摘列部分典型的内容:

# cat /proc/568/maps
로그인 후 복사

버퍼: 4096 kB

캐시: 17260 kB

SwapCached:       0 kB

Act ive:       21304 kB

비활성:       19248 kB

SwapTotal:         0 kB

SwapFree:           0 kB

더티:         0 kB

쓰기:         0 kB

AnonPages:       19216 kB

매핑:          2472kB

슬랩:         6900kB

S회수 가능:     924kB

S회수 취소:       5976kB

PageTables: 460kB

NFS_Unstable: 0kB

Bounce: 0kB

CommitLimit: 62060kB

Committed_AS: 2886 4kB

VmallocTotal: 442368kB

Vmalloc 사용: 46984kB

Vmalloc청크: 393212kB

 00008000-0036a000 r-xp 00000000 00:0e 236        /home/hik/hicore

00372000-003a5000 rw-p 00362000 00:0e 236        /home/hik/hicore

003a5000-00e28000 rwxp 003a5000 00:00 0          [heap]

40000000-40005000 r-xp 00000000 01:00 94         /lib/ld-uClibc.so.0

416db000-41770000 rw-s c2005000 00:0f 68         /dev/mem

b51fc000-b5200000 rwxp b51fc000 00:00 0

…….

be1fc000-be200000 rwxp be1fc000 00:00 0

be93b000-be950000 rwxp befeb000 00:00 0          [stack]

第一行:从r-xp可知其权限为只读、可执行,该段内存地址对应于执行文件的代码段,程序的代码段需加载到内存中才可以执行。由于其只读,不会被修改,所以在整个系统内共享。

第二行:从rw-p可知其权限为可读写,不可执行,该段内存地址对应于执行文件的数据段,存放执行文件所用到的全局变量、静态变量。

第三行:从rwxp可知其权限是可读写,可执行,地址空间向上增长,而且不对应文件,是堆段,进程使用malloc申请的内存放在堆段。每个进程只有一个堆段,不论是主进程,还是不同的线程申请的内存,都反映到到进程的堆段。堆段向上增长,最大可以增长到1GB的位置,即0x40000000,如果大于1GB,glibc将采用mmap的方式,为堆申请一块内存。

第四行:是程序连接的共享库的内存地址。

第五行:是以mmap方式映射的虚拟地址空间。

第六、七行:是线程的栈区地址段,每个线程的栈大小都是16K。

第八行:是进程的栈区。关于栈段,每个线程都有一个,如果进程中有多个线程,则包含多个栈段。

三、当前系统总内存的统计

1、进程占用的总内存可以通过上述maps表计算出来。

2、当系统运行起来以后,会把应用层相关的文件挂载到tmpfs文件系统下,海思系统下这部分大概有13M左右,这部分内存是以cache方式统计出来的,但是这部分内存cache无法通过回收策略或者显式的调用释放掉。

3、根文件系统ramdisk占用的内存。

4、当前系统保留内存的大小,可以通过查看/proc/sys/vm/min_free_kbytes来获取或者修改此内存的大小。

5、当然,当系统运行起来后,还应该留有一定的内存用于在硬盘读写时做cache或者网络负荷比较高时分配skb等,一般需要30M以上。

四、对调试内存泄露类问题的一些启示

当进程申请内存时,实际上是glibc中内置的内存管理器接收了该请求,随着进程申请内存的增加,内存管理器会通过系统调用陷入内核,从而为进程分配更多的内存。

针对堆段的管理,内核提供了两个系统调用brk和mmap,brk用于更改堆顶地址,而mmap则为进程分配一块虚拟地址空间。

当进程向glibc申请内存时,如果申请内存的数量大于一个阀值的时候,glibc会采用mmap为进程分配一块虚拟地址空间,而不是采用brk来扩展堆顶的指针。缺省情况下,此阀值是128K,可以通过函数来修改此值。

#include <malloc.h>
로그인 후 복사

Int mallopt(int param, int value)

Param的取值分别为M_MMAP_THRESHOLD、M_MMAP_MAX。

Value的取值是以字节为单位的。

M_MMAP_THRESHOLD是glibc中申请大块内存阀值,大于该阀值的内存申请,内存管理器将使用mmap系统调用申请内存,如果小于该阀值的内存申请,内存管理器使用brk系统调用扩展堆顶指针。

M_MMAP_MAX是该进程中最多使用mmap分配地址段的数量。

如果在实际的调试过程中,怀疑某处发生了内存泄露,可以查看该进程的maps表,看进程的堆段或者mmap段的虚拟地址空间是否持续增加,如果是,说明很可能发生了内存泄露,如果mmap段虚拟地址空间持续增加,还可以看到各个段的虚拟地址空间的大小,从而可以确定是申请了多大的内存,对调试内存泄露类问题可以起到很好的定位作用。


위 내용은 Linux에서 메모리 통계 및 메모리 누수를 확인하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿