c++ 获得linux进程内存大小,[c++,kernel] 获取当前进程内存占用量

实验目的:

通过系统调用实现获取当前正在运行的进程占用系统中的内存资源的最大值,

由于涉及到系统库中的API 所以将其归类为kernel方向。

实验思路:

希望本程序可以被 windows 和 linux/unix  所兼容,所以编程实现时过程中通过宏定义

方法来判断当前平台类型,然后根据不同的平台类型调用不同的系统  API 来得到系统的参数。

但是在代码中仅给出 window 下面的代码及说明(使用 #ifdef 来分辨平台在 vs2012 中没有调试成功)

实验环境:

vs2012 , c++

实验代码:

//memChecker.h

#ifndef MEMCHECKER_H

#define MEMCHECKER_H

namespace memChecker

{

long get_maxMem_kb () ;

}

#endif //MEMCHECKER_H

//memChecker.cpp

#include "memChecker.h"

#include

#include

using namespace memChecker;

long memChecker::get_maxMem_kb()

{

PROCESS_MEMORY_COUNTERS pmc ;

GetProcessMemoryInfo(GetCurrentProcess() , &pmc, sizeof(pmc));

return pmc.PeakWorkingSetSize / 1024 ;

}

//Main.cpp

#include

#include

#include

#include "memChecker.h"

using namespace std ;

int main ( int argc , char * argv [] )

{

cout<

long usage = memChecker::get_maxMem_kb() ;

cout<

system("pause") ;

return 0 ;

}

其中,对于 memChecker.cpp 中所涉及到的 windows 内核代码注释如下:

1. 变量 PROCESS_MEMORY_COUNTERS

1.

PROCESS_MEMROY_COUNTERS

typedef struct _PROCESS_MEMORY_COUNTERS

{

DWORD cb ;

DWORD PageFaultCount ;

SIZE_T PeakWorkingSetSize ;

SIZE_T WorkingSetSize ;

SIZE_T QuotaPeakPagePoolUsage ;

SIZE_T QuotaPagedPoolUsage ;

SIZE_T QuotaPeakNonPagedPoolUsage ;

SIZE_T QuotaNonPagedPoolUsage ;

SIZE_T PagefileUsage ;

SIZE_T PeakPagefileUsage ;

} PROCESS_MEMORY_COUNTERS , *PROCESS_MEMORY_COUNTERS ;

PROCESS_MEMORY_COUNTERS

这个变量是用来记录系统中当前进程,也就是 PROCESS_MOMORY_COUNTERS

变量所在的这个程序运行起来之后对应的这个进程对系统内存资源的使用量的一系列统计数据。

其中 DWORD 是一个 Microsoft 中定义的一个变量类型,

可以将它看作是一个类似于char 类型,不过 char 对应的是一个字符号,

而DWORD 是 double word ,每个 word 是 2个字节的大小, 那么DWORD 就是长度为 4 个字节大小的一个变量类型。

而SIZE_T 是属于c++标准库中的一个类型, 他是一个与机器相关的无符号的类型(unsigned)。

1. cb:

以字节为单位用来记录 当前这个 PROCESS_MEMORY_COUNTERS 类型对应的变量

所占的大小,即

PROCESS_MEMORY_COUNTERS pmd ;

pmd.cb = sizeof(pmd) ;

2. PageFaultCount:

用来记录发生页错误的次数

3. PeakWorkingSetSize

以字节为单位,用来记录当前工作集的大小

4. QuotaPeakPagedPoolUsage

以字节为单位,记录分页池中最大的使用量

5. QuotaPagedPoolUsage

以字节为单位,记录当前分页池中的使用量(即分页池中被进程申请的全部页面的大小(kb))

6. QuotaPeakNonPagedPoolUsage

以字节为单位记录非分页池中最大的空间申请量

7. QuotaNonPagedPoolUsage

以字节为单位,记录非分页池中当前空间的申请使用量

(注: 这里的空间均是指系统中的内存空间 ;我想:在分页池中空间的分配是以 页面为单位的,

而在非分页池中内存空间的分配大小是由申请空间大小来分配的)

8.PagefileUsage

commit charge is a term used in Microsoft Windows operating systems to describe

the total amount of pageable virtual address space for

which no backing store is assigned other than the pagefile.

其中这些虚拟地址空间中全部是是页面文件存放空间,而不包含缓存空间(backing store)>

而这个PagefileUsage 是以字节为单位来记录当前进程所占用的 Commit Charge 类型内存的大小数值的。

Commit Charge 在官网中也给出解释,说它是有内存管理者为当前正在运行的继承所分配的全部内存的一个总数。

9. PeakPagefileUsage

这个变量是用来以字节为单位记录,系统为当前进程在该进程的生命周期内所分配的

最大Commit Charge类型内存的最大值。

2. method: GetProcessMemoryInfo

2), Mehtod : GetProcessMemoryInfo

从它的名字即可推知它的功能,用来获取明确指定进程

的内存使用情况信息。

这个系统API的设计方式与 unix/linux 常用的系统API 设计方式很相似:

都是通过返回值来返回该方法执行的是否正确的情况,

并且通过 "值-地址" 的传参方式来得到该函数真正的返回数值。

这一点"值-地址" 的传参方式可以从如下的API描述中看出来:

即, _In_ 表示的是,该参数是传入到方法中的数值,

_Out_ 所表示的是,该参数传入的是一个指向空间的地址变量,(指针),

在该函数中得到运行结果之后,通过传入的指针将结果写入到指针所指向的空间中即可。

这样在方法结束返回到主调方法中之后,存放结果的空间并不会随着子方法的运行结束

而被释放掉,主调方法仍旧可以通过刚刚传入到子方法中的指针来对该指针指向空间进行访问。

其中,BOOL 后面的 WINAPI 以意思是表明该函数是 windows中的系统API,

系统 API 并不是系统调用,而是系统为程序员使用系统调用提供的一个接口函数。

在该API中(系统API)调用的是真正的内核中的系统方法,也就是系统调用。

知道这一点十分重要,因为这会直接影响你编写程序所站的角度:

是以一名使用者的身份,还是以计算机的身份。

如果你想修改系统内核代码的话,是必须要站在计算机的身份来思考整个程序的走向的。

反之,如果你只想访问,读取系统当前的某些状态,

那么你必须以使用者的身份来思考问题。

BOOL WINAPI GetProcessMemoryInfo

(

_In_ HANDLE Process ,

_Out_ PROCESS_MEMORY_COUNTERS ppmc,

_IN_ DWORD cb

) ;

其中第一个参数是用来传入想要获取信息的进程对象的句柄,

因为本方法只是想获取当前的进程使用内存的情况,

所以在本方法中调用一个

GetCurrentProcess() 即可得到当前进程的句柄。

这里所说的句柄,类似于对象的一种引用(reference),通过引用可以

确定该对象(该进程)在系统中存放的位置、大小等相关信息。

虽然普通类的引用(reference )于Process 的句柄(handler )亦或是一个对象实体的指针(pointer ),

所起到的作用都是相类似的,在这里撇开指针不说,只谈引用和句柄。

二者之所以区分对待,是因为Process 这个数据结构对象是系统内部的数据结构对象,

而引用所指代的应该是用户自定义的类对象,二者占用的内存空间应该是有所区别的。

系统对引用和句柄的维护方式,即其相应的空间回收、访问和管理方式有所不同的原因>

1.Process : [传入参数] 接收要分析占用内存空间信息的进程对象的句柄

2.ppmc:[传入、传出参数] 接收指向 PROCESS_MEMORY_COUNTERS 结构体对象的指针

通过传入的指针将分析结果记录到该指针指向的空间中,方法结束空间不会被回收

(空间是由系统为主调方法分配的,而并非是 GetProcessMemoryInfo 方法中的局部变量占用的空间)

3. cb :[传入参数] 该数值用来描述 PROCESS_MEMORY_COUNTERS 实体指针所指向的实体占用空间的大小。

即 cb = sizeof (*pmd ) ; 或是 cb = (*ppmc)->cb ;

3. Method :GetCurrentProcess

3).Method: GetCurrentProcess()

HANDLE WINAPI GetCurrentProcess (void ) ;

该方法是 windows 中的系统API , 返回值是当前正在运行的进程的句柄对象。

那什么叫做当前运行的进程呢? 就是你调用该 GetCurrentProcess() 语句所在的程序,

在该程序被运行起来之后,对于 GetCurrentProcess () 而言就是它的当前正在运行的进程。

实验不足与改进:

这个代码中不能加入自动识别运行平台的宏定义,很是遗憾没能够写上 linux 访问内存使用信息的系统函数。

宏定义还需要在仔细学习一下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值