精华内容
下载资源
问答
  • 2016-07-25 00:44:03

    Windows内存修改

    你可能用过金山游侠,GameMaster8,Cheat Engine,那你有没有想过自己实现一个简易的内存修改工具?本文将介绍在Windows平台下实现一个简易内存修改工具的方法,只要你有一些windows内存管理机制的基本知识以及一定的c++编程能力,你就可以利用本文介绍的Windows内存管理API自己实现一个简易的内存修改工具。
    本文将先介绍Windows的相关API,然后介绍下利用其实现内存修改工具的思路,最后介绍一个自己在windows api基础上封装的API(以下称内存管理及修改API或内存修改API),包括各API函数的说明以及如何通过对这套API的简单调用实现内存修改。
    关于内存管理API以及简易的演示程序,代码较长,感兴趣的朋友可去https://github.com/jimth001/Windows-Memory-Modification.git 查看。

    相关的windows API

    1) GetSystemInfo

    用来填充SYSTEM_INFO结构体信息,函数原型如下:

    
    voidWINAPI GetSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo)

    lpSystemInfo:指向一个供函数返回信息的SYSTEM_INFO结构体。SYSTEM_INFO定义如下:

    typedefstruct _SYSTEM_INFO {
    
    union {
    
    DWORD dwOemId;// Obsoletefield...do not use
    
    struct {
    
           WORD wProcessorArchitecture;//处理器架构
    
    WORD wReserved;
    
    } DUMMYSTRUCTNAME;
    
    } DUMMYUNIONNAME;
    
    DWORD dwPageSize;//分页大小
    
    LPVOID lpMinimumApplicationAddress;//最小寻址空间
    
    LPVOID lpMaximumApplicationAddress;//最大寻址空间
    
    DWORD_PTR dwActiveProcessorMask;//处理器掩码
    
    DWORD dwNumberOfProcessors;//处理器数目
    
    DWORD dwProcessorType;//处理器类型
    
    DWORD dwAllocationGranularity;//虚拟内存空间的粒度
    
    WORD wProcessorLevel;//处理器等级
    
    WORD wProcessorRevision;//处理器版本
    
    } SYSTEM_INFO, *LPSYSTEM_INFO;

    2) GetPerformanceInfo

    用来填充PERFORMANCE_INFORMATION结构体信息,用法类似于GetSystemInfo,比GetSystemInfo多一个参数,第二个参数是结构体的大小

    PERFORMANCE_INFORMATION结构体定义如下:

    typedef struct _PERFORMANCE_INFORMATION {
    
    DWORD  cb;//该结构体大小,调用GetPerformanceInfo前要先将其初始化
    
    SIZE_T CommitTotal;// 系统当前提交的页面总数
    
    SIZE_T CommitLimit;// 系统可提交的页面总数
    
    SIZE_T CommitPeak;// 系统历史提交页面峰值
    
    SIZE_T PhysicalTotal;// 按页分配的总的物理内存
    
    SIZE_T PhysicalAvailable;// 系统当前提交的页面总数
    
    SIZE_T SystemCache;
    
    SIZE_T KernelTotal;
    
    SIZE_T KernelPaged;
    
    SIZE_T KernelNonpaged;
    
    SIZE_T PageSize;// The size of a page, in bytes.
    
    DWORD  HandleCount;// The current number of open //handles.
    
    DWORD ProcessCount;//
    
    DWORD ThreadCount;//
    
    }PERFORMANCE_INFORMATION, *PPERFORMANCE_INFORMATION;

    3) CreateToolhelp32Snapshot

    CreateToolhelp32Snapshot可以通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。

    函数原型如下:

    HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS(在快照中包含系统中所有的进程)等

    DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0

    );

    调用成功,返回快照的句柄,否则返回INVALID_HANDLE_VALUE

    4) Process32First

    process32First是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,我们可以利用process32First函数来获得第一个进程的句柄。

    函数原型如下:

    
    BOOL WINAPI Process32First(
    
    HANDLE hSnapshot,//_in(in表示该参数是导入数据的)
    
    LPPROCESSENTRY32 lppe//_out(out表示该参数是导出数据的)
    
    //是指向PROCESSENTRY32结构的指针
    
    );

    PROCESSENTRY32 结构定义如下:

    typedef struct tagPROCESSENTRY32 {
    
    DWORD dwSize; // 结构大小;
    
    DWORD cntUsage; // 此进程的引用计数;
    
    DWORD th32ProcessID; // 进程ID;
    
    DWORD th32DefaultHeapID; // 进程默认堆ID;
    
    DWORD th32ModuleID; // 进程模块ID;
    
    DWORD cntThreads; // 此进程开启的线程计数;
    
    DWORD th32ParentProcessID;// 父进程ID;
    
    LONG pcPriClassBase; // 线程优先权;
    
    DWORD dwFlags; // 保留;
    
    WCHAR szExeFile[MAX_PATH]; // 进程全名;
    
    } PROCESSENTRY32;

    5) Process32Next

    Process32Next是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,我们可以利用Process32Next函数来获得下一个进程的句柄。

    函数原型如下:

    Process32Next(Handle hsnapShot,LPPROCESSENTRY32 lppe)

    若成功获取了下一个进程的信息则返回TRUE,与CreateToolhelp32Snapshot,Process32First搭配使用,用来枚举当前系统快照相关的所有进程。

    6) GetProcessMemoryInfo

    用于获取指定进程的内存使用情况。

    函数原型如下:

    GetProcessMemoryInfo(
    
    HANDLE Process,
    
    PPROCESS_MEMORY_COUNTERS ppsmemCounters,
    
    DWORD cb
    
    );

    Process是获取内存使用情况的进程句柄。

    ppsmemCounters是返回内存使用情况的结构。

    cb是结构的大小。

    PPROCESS_MEMORY_COUNTERS结构定义如下:

    
    typedef struct _PROCESS_MEMORY_COUNTERS{
    
       DWORD  cb;
    
       DWORD  PageFaultCount;//缺页中断次数.
    
       SIZE_T PeakWorkingSetSize;//使用内存峰值(峰值工作集)
    
       SIZE_T WorkingSetSize;//当前使用内存(当前工作集)
    
       SIZE_T QuotaPeakPagedPoolUsage;// 使用页面缓存池高峰
    
       SIZE_T QuotaPagedPoolUsage;//当前使用页面缓存池
    
    SIZE_T QuotaPeakNonPagedPoolUsage;// 使用非分页缓存池高//峰
    
       SIZE_T QuotaNonPagedPoolUsage;// 使用非分页缓存池
    
       SIZE_T PagefileUsage;// 使用分页文件
    
       SIZE_T PeakPagefileUsage;// 使用分页文件高峰
    
    } PROCESS_MEMORY_COUNTERS,*PPROCESS_MEMORY_COUNTERS;

    7) OpenProcess

    OpenProcess 函数用来打开一个已存在的进程对象,并返回进程的句柄。

    函数原型如下:

    HANDLE OpenProcess(
    
    DWORD dwDesiredAccess, //期望得到的访问权限(标志)
    
    BOOL bInheritHandle, // 是否继承句柄
    
    DWORD dwProcessId// 进程标识符
    
    ); 

    如成功,返回值为指定进程的句柄。

    如失败,返回值为空,可调用GetLastError获得错误代码。

    8) VirtualQueryEx

    用来查询地址空间中内存地址的信息。

    DWORD VirtualQueryEx(
    
    HANDLE hProcess,
    
    LPCVOID lpAddress,
    
    PMEMORY_BASIC_INFORMATION lpBuffer,
    
    DWORD dwLength
    
    );

    参数说明如下:

    hProcess 进程句柄。

    lpAddress 查询内存的地址。

    lpBuffer 指向MEMORY_BASIC_INFORMATION结构的指针,用于接收内存信息。

    dwLength MEMORY_BASIC_INFORMATION结构的大小。

    返回值:函数写入lpBuffer的字节数,如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败

    MEMORY_BASIC_INFORMATION定义如下:

    
    typedef struct _MEMORY_BASIC_INFORMATION {
    
    PVOID  BaseAddress;// 与lpAddress参数的值相同,但是四舍五入为页面的边界值。
    
    PVOID  AllocationBase;// 指明用VirtualAlloc函数分配内存区域的基地址。lpAddress在该区域之内。
    
    DWORD  AllocationProtect;//区域被初次保留时赋予的保护属性
    
    SIZE_T RegionSize;// 用于指明内存块从基地址即BaseAddress开始的所有页面的大小(以字节为计量单位)这些页面与含有用LpAddress参数设定的地址的页面拥有相同的保护属性、状态和类型。
    
    DWORD State;//页面的状态,有三种可能值://MEM_COMMIT、MEM_FREE和MEM_RESERVE,
    
    //committed:已在物理介质上存在
    
    //free:空闲的,不可访问,可分配的。
    
    //reserved:预留的
    
    DWORD  Protect;//页面的属性,其可能的取值与//AllocationProtect相同
    
    DWORD  Type;//该内存块的类型,有三种可能值://MEM_IMAGE、MEM_MAPPED和MEM_PRIVATE
    
    } MEMORY_BASIC_INFORMATION,*PMEMORY_BASIC_INFORMATION;

    9) ReadProcessMemory

    读取指定进程私有地址空间中指定地址的数据。

    函数原型如下:

    
    BOOL ReadProcessMemory(
    
    HANDLE hProcess,// [in]远程进程句柄。被读取者,若为//INVALID_HANDLE_VALUE,则目标进程为自身进程
    
    PVOID pvAddressRemote,// [in]远程进程中的内存地址。从何处读取
    
    PVOIDpvBufferLocal, // [out]本地进程中内存地址. 函数将读取的//内容写入此处
    
    DWORD dwSize, // [in]要传送的字节数。要写入多少
    
    PDWORDpdwNumBytesRead//[out]实际传送的字节数. 函数返回时报告//实际写入多少
    
    );

    10) WriteProcessMemory

    将数据写到指定进程的指定地址。

    函数原型和参数说明基本同ReadProcessMemory,只是数据流向不同。

    11) VirtualAllocEx

    VirtualAllocEx函数的作用是在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0。

    函数原型如下:

    
    LPVOID VirtualAllocEx(
    
    HANDLE hProcess,// 申请内存所在进程的句柄
    
    LPVOIDlpAddress,// 保留页面的内存地址;一般用NULL自//动分配 。
    
    SIZE_TdwSize,// 欲分配的内存大小,字节单位;注意实际//分配的内存大小是页内存大小的整数倍
    
    DWORD flAllocationType,//
    
    DWORD flProtect//
    
    );

    执行成功就返回分配内存的首地址,否则返回NULL。

    12) VirtualFreeEx

    在其他进程中释放申请的虚拟内存空间。

    
    BOOL WINAPI VirtualFreeEx(
    
    HANDLEhProcess,// 目标进程的句柄。该句柄必须拥有//PROCESS_VM_OPERATION 权限。
    
    LPVOIDlpAddress,//指向要释放的虚拟内存空间首地址的指//针。如果 dwFreeType 为 MEM_RELEASE, 则该参数必须为//VirtualAllocEx的返回值
    
    SIZE_T dwSize,// 虚拟内存空间的字节数。
    
    //如果 dwFreeType 为MEM_RELEASE,则 dwSize 必须为0 . //按 VirtualAllocEx审请时的大小全部释放。
    
    //如果dwFreeType 为MEM_DECOMMIT, 则释放从lpAddress //开始的一个或多个字节 ,即 lpAddress +dwSize
    
    DWORDdwFreeType
    
    );

    返回值:

    成功:为非0值(零)。

    失败:为0(零)。可调用GetLastError获取失败的消息。

    13) GetModuleFileNameEx

    获取指定进程已加载模块的文件的完整路径

    
    DWORD WINAPI GetModuleFileNameEx(
    
     _In_   HANDLE  hProcess,//指定进程的句柄
    
     _In_opt_ HMODULE  hModule,// 要处理的模块
    
      _Out_   LPTSTR  lpFilename,// 指向接收到模块的完全限定路//径null结尾的缓冲区。如果文件名的大小比n大小参数的值越大,//文件名被截断
    
     _In_   DWORD   nSize//nSize是这个缓冲区的大小,用于防止溢出
    
    );

    如果函数成功,返回值指定复制到缓冲区中的字符串的长度。如果函数失败,返回值是零。若想获得更多的错误信息,调用GetLastError。

    14) VirtualProtectEx

    
    BOOL WINAPI VirtualProtectEx(
    
     _In_  HANDLE hProcess,
    
     _In_  LPVOID lpAddress,
    
     _In_  SIZE_T dwSize,
    
     _In_  DWORD  flNewProtect,
    
      _Out_PDWORD lpflOldProtect
    
    );

    内存修改实现的基本原理:

    在权限足够的情况下,打开想要修改的进程,我们可以获得其私有地址空间所有内存块的信息,然后进行筛选作为搜索的候选块。首次搜索时,使用ReadProcessMemory读取这些候选块,根据选择的内存对齐原则进行遍历,把读取到的数据转化为搜索类型,比对是否一致,若一致,将其地址信息记录在相应的数据结构中(search_info)。当想要搜索的数据变动后,再次搜索,这时只按照search_info记录的地址进行读取,这样就能逐渐搜索出想要找的变量。若确定了想要找的变量,将想要写入的值转换为字符串(本项目中使用unsigned char*),使用WriteProcessMemory写入,这样就完成了修改。

    内存管理及修改API(made by myself)说明:

    1) 获取机器分页大小

     DWORD  WINAPI getSystemPageSize();

    2) 提升权限

     BOOL WINAPIEnablePrivileges();

    3) 获取进程列表

    /* OUTvector<PROCESS_MEMORY_COUNTERS>&
     OUTvector<PROCESSENTRY32>&
     return string描述进程信息*/
     string  WINAPIgetProcessList(vector<PROCESS_MEMORY_COUNTERS>& vct_pmc,vector<PROCESSENTRY32>& vct_pe32);

    4) 首次搜索

    /*
     vector<MEMORY_BASIC_INFORMATION>memInfo,筛选出的待搜索块
    
     search_info&v_s_rslt,保存搜索结果的数据结构
    
     HANDLE handle,进程句柄
    
     DWORD s_type,搜索类型,支持FLOAT_T INT_TDOUBLE_T STRING_T
    
     DWORD pagesize,系统页面大小
    
     char* charexpval,要搜索的STRING_T值
    
     int *intexpval,要搜索的INT_T值
    
     float*floatexpval,要搜索的FLOAT_T值
    
     double*doubleexpval要搜索的DOUBLE_T值
    
     */
    
     BOOL WINAPIsearchAll(vector<MEMORY_BASIC_INFORMATION> memInfo, search_info&v_s_rslt, HANDLE handle, DWORD s_type, DWORD pagesize, char* charexpval,int *intexpval, float *floatexpval, double *doubleexpval);

    5) 附加到进程(打开进程)

    /*
     DWORD IN pid,要打开的进程
    
     DWORD OUT hProcess成功后返回的进程句柄
    
     */
    
     BOOL WINAPIattachToProcess(DWORD Pid, HANDLE & hProcess);

    6) 按属性筛选要搜索的内存块

    /*
    HANDLE INhProcess 进程句柄
    
    vector OUTmemInfo 保存内存块信息的数据
    
    vector<MEMORY_BASIC_INFORMATION>
    
    DWORD INstateFilter 按state类型过滤内存块
    
    DWORD IN typeFilter 按type类型过滤内存块
    
    DWORD IN protectFilter 按protect类型过滤内存块
    
    */
    
    BOOL WINAPI getProcessMemBlockEX(HANDLE hProcess, 
    
    vector<MEMORY_BASIC_INFORMATION>& memInfo,DWORD stateFilter, DWORD 
    
    typeFilter, DWORD protectFilter, DWORD* memSize);

    7) 申请一块虚存区

    /*
     int size,申请的虚存大小
    
     HANDLE handle进程句柄
    
     */
    
     LPVOID WINAPI AllocVirtual(intsize, HANDLE handle);

    8) 释放虚存区

    /*
     LPVOID Buffer,释放的虚地址指针
    
     HANDLE handle进程句柄
    
     */
    
     BOOL WINAPIFreeVirtual(LPVOID Buffer, HANDLE handle);

    9) 再次搜索

    /*
     HANDLE hProcess,//进程句柄
    
     search_info &v_s_rslt,//保存上次搜索信息的数据结构
    
     LPVOIDexpected_val//新的搜索值,对字符串传入char*而不是string *
    
     */
    
    BOOL WINAPI nextScan(HANDLE hProcess,search_info & v_s_rslt, LPVOID 
    
    expected_val);

    10) 将数据写入指定线性地址

    /*
    HANDLEhProcess,//要写入的进程
    
    LPVOID address,//要写入的地址
    
    void * write_val,//要写入的变量指针,只能是string,int,double,
    
    float四种
    
    DWORD valType,//写入的变量类型,可选值见头文件宏定义
    
    int stringAppendZeroNUM,//字符串后追加的字符数量
    
    char endSet//字符串后追加字符,内存中string和char结尾不同
    
    */
    
    BOOL WINAPI writeData(HANDLE hProcess, LPVOID address,void * 
    
    write_val, DWORD valType, int stringAppendZeroNUM,charendSet);

    11) 设置mylasterror的函数

     voidmySetLastError(DWORD e);

    12) 内部的error code函数,通过此获取错误类型,头文件有错误类型定义

     DWORDmyGetLastError();

    13) 必要的初始化函数,必须先初始化,目前只有检查对齐类型操作

     voidinit_for_mem_manage();

    14) 检查机器内存对齐类型

     voidcheck_mem_align_scheme();

    15) 获取内存使用的系统信息

    string WINAPI getSystemInfo_toString();

    16) 获取内存性能使用相关信息

    string WINAPI getPerformanceInfo_toString();

    17) 获取进程私有地址空间信息

    string WINAPI processInfoToString(PROCESSENTRY32 pe, PROCESS_MEMORY_COUNTERS*pmc);

    内存修改API相关数据结构的定义:

    typedef struct search_result_i{
    
       LPCVOIDbaseAddress;//基址
    
       DWORDoffset;//偏移量
    
       inti_val;//内存中的值
    
    }search_i_list;
    
    typedef struct search_result_d{
    
       LPCVOIDbaseAddress;
    
       DWORDoffset;
    
       doubled_val;
    
    }search_d_list;
    
    typedef struct search_result_f{
    
       LPCVOIDbaseAddress;
    
       DWORDoffset;
    
       floatf_val;
    
    }search_f_list;
    
    typedef struct search_result_s{
    
       LPCVOIDbaseAddress;
    
       DWORDoffset;
    
       strings_val;
    
    }search_s_list;
    
    typedef struct search_info{
    
       DWORDs_type;//搜索类型
    
       vector<struct search_result_i> i_list;//int搜索结果
    
       vector<struct search_result_d> d_list;//double搜索结果
    
       vector<struct search_result_f> f_list;//float搜索结果
    
       vector<struct search_result_s> s_list;//字符串搜索结果
    
       inti_exp;//搜索值
    
       doubled_exp; //搜索值
    
       floatf_exp; //搜索值
    
       strings_exp; //搜索值
    
    }search_info;//保存搜索信息的数据结构

    内存修改API调用的基本流程:

    EnablePrivileges提权

    init_for_mem_manage必要的初始化工作,目前只是判断大小端机器

    getSystemPageSize获取系统页大小,后面做参数

    getProcessList获取进程列表

    用户输入pid

    attachToProcess附加到指定进程

    getProcessMemBlockEX获取指定state,type,protect属性的内存块,

    后面搜索只会在这些块里搜

    用户选择类型和搜索值

    searchAll首次搜索,结果保存在struct search_info

    再次输入

    nextScan再次搜索

    当确认搜索到想要的数据时,根据其地址使用writeData进行修改。

    更多相关内容
  • 当遇到应用偶发性出问题时,需要分析是否因为该应用的进程内存使用率瞬时值过高或服务器CPU过高导致的,每隔5秒记录一次,自动监控并记录便于分析问题。
  • windows查看进程内存使用记录

    万次阅读 2012-12-07 19:02:21
    当写完一个工程,我们往往都会需要去check一下该工程存不存在内存...2. 利用第三方软件查看该工程所建进程内存使用记录,通过查看峰值是不是随着 执行时间的增加而增加,从而来判断该工程是否存在内存泄露问题(当然

    当写完一个工程,我们往往都会需要去check一下该工程存不存在内存泄露问题。

    如果有内存泄露问题的话,那么若程序的主循环次数越多,数据越大,则内存问题会越明显。


    一般有两种方案来check这个问题:

    1. 在工程中,写代码调用内存相关接口

    2. 利用第三方软件查看该工程所建进程的内存使用记录,通过查看峰值是不是随着

    执行时间的增加而增加,从而来判断该工程是否存在内存泄露问题(当然要给大数据,我这里指的大数据是指能够引起工程内存消耗更大的数据)。


    由于我只是想粗略的check下该工程是不是有内存泄露情况,所以我选择了

    windows自带的工具C:\Windows\System32\perfmon.exe 这是win7路径

    1.双击“性能监视器”


    2. 在绘制区域右击点击“添加计数器”


    3. 选择“Process”中的“working Set”

    and then

    4.在“选定对象的实例”中选择自己要观察的进程“XXX”



    5.点击“添加”,然后确定



    6.右击选择“属性”,设置显示比例以及持续时间



    7.效果图如下所示,最后一条线是绘制线可以忽略







    展开全文
  • Windwos Server 2008 中出现物理内存占用极高甚至宕机,但任务管理器中各进程内存占用并不多,查来查去也不知道什么原因的情况。使用RAMMAP的工具检查,发现这些内存被Metafile占用了,经查阅Metafile是系统缓存的...
  • Windows记录CPU和内存的方法
  • Android应用进程内存管理

    千次阅读 2018-02-11 12:38:35
    Android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知道Java,就能更清楚这机制了.其实和java的垃圾回收机制类似,系统有一个规则来回收内存.进行内存调度有个阀值,只有低于这个值...

    Android的原理-不需要太多的剩余内存

           不用在意剩余内存的大小. Android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知道Java,就能更清楚这机制了.其实和java的垃圾回收机制类似,系统有一个规则来回收内存.进行内存调度有个阀值,只有低于这个值系统才会按一个列表来关闭用户不需要的东西.当然这个值默认设置得很小,所以你会看到内存老在很少的数值徘徊.但事实上他并不影响速度.相反加快了下次启动应用的速度.

        到这里有人会说了,那为什么内存少的时候运行大型程序会慢呢?其实很简单,在内存剩余不多时打开大型程序,会触发系统自身的进程调度策略,这是十分消耗系统资源的操作,特别是在一个程序频繁向系统申请内存的时候.这种情况下系统并不会关闭所有打开的进程,而是选择性关闭,频繁的调度自然会拖慢系统.所以,论坛上有个更改内存阀值的程序可以有一定改善. 但改动也可能带来一些问题,取决于值的设定.
        那么,进程管理软件有无必要呢?有的.就是在运行大型程序之前,你可以手动关闭一些进程释放内存,可以显著的提高运行速度.但一些小程序,完全可交由系统自己管理.我就说说安卓Android后台的原理, Android的应用在被切换到后台时,它其实已经被暂停了,并不会消耗cpu资源,只保留了运行状态.所以为什么有的程序切出去重进会到主界面.但是,一个程序如果想要在后台处理些东西,如音乐播放,它就会开启一个服务.服务可在后台持续运行,所以在后台耗电的也只有带服务的应用了.这个在进程管理软件里能看到,标签是service.至于广播什么的我就不涉及了.所以没有带服务的应用在后台是完全不耗电的,没有必要关闭.这种设计本来就是一个非常好的设计,下次启动程序时,会更快,因为不需要读取界面资源,何必要关掉他们抹杀这个安卓Android的优点呢?
        还有一个.为什么Android一个应用看起来那么耗内存.大家知道,安卓Android上的应用是java,当然需要虚拟机,而安卓Android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机.这样设计的原因是可以避免虚拟机崩溃导致整个系统崩溃,但代价就是需要更多内存.

        以上这些设计确保了安卓Android的稳定性,正常情况下最多单个程序崩溃,但整个系统不会崩溃,也永远没有内存不足的提示出现.大家可能是被windows毒害得太深了,总想保留更多的内存,但实际上这并不一定会提升速度,相反却丧失了程序启动快的这一系统特色,很没必要.

    至于为什么开了大程序或者开了好几个程序之后切换会变慢,我的理解如下:
    1.大程序A已经开启,占用70%内存,如果再想运行一个B,需要50%的内存,则就需要一个将A从内存中释放或者压缩的过程,所以表现出来的就是慢一会儿
    2.A\B\C\D\E共占用内存80%,运行新程序Z需要 20%的内存,系统内存因为没见过剩余0的时候,也就是应该剩一部分空闲内存,那么就需要从A~E这几个程序中选择一个或者几个来关闭,这一过程也需要耗费系统资源,所以会慢一会儿
    3.也就是说你手动去杀程序的时候,就是替系统在释放内存,就算你不杀,在需要内存的时候系统也会自动释放.
    4.不在后台运行的程序(没服务的),即使不杀也不会耗电.在后台运行的(有服务的)程序,如后台放歌,当然会耗电.
    5.不是说杀进程没用,不然作者就不会推荐进程管理软件了.哪个带服务耗电哪个后台一直在运行,看服务就能看出来,这样的该杀.
    6,qq举例,正常的退,会在进程管理里留下qq的运行状态,但不耗电不占 cpu,如果你只是切换出去(按小房子而不是退出)那么自然会耗电,因为程序还在运行.
                  android5个程序进程  

    android的所有5个程序进程的级别高低空进程是最低的,它存在的目的是为了下次打开这个软件的时候可以更加方便快速(这是个很好的设计目的),而一旦需要清理出更多内存空间时,它也是被系统自动的最优先清除的


    系统进程级别图,级别越低的会越快越早的被系统智能清理掉.用进程管理主动去清除空置程序绝对是违反android系统的设计本意的,是一种可笑的傻做法!

                   关于android内存管理的原理
    Android什么时候结束进程?结束哪个进程呢?之前普遍的认识Android是依据一个名为LRUlast recently used 最近使用过的程序)列表,将程序进行排序,并结束最早的进程XDA的楼主又进一步对这个管理机制进行研究,有了如下发现:

    1.系统会对进程的重要性进行评估,并将重要性以“oom_adj”这个数值表示出来,赋予各个进程;(系统会根据“oom_adj”来判断需要结束哪些进程,一般来说,oom_adj”的值越大,该进程被系统选中终止的可能就越高)

    2.前台程序的“oom_adj”值为0,这意味着它不会被系统终止,一旦它不可访问后,会获得个更高的“oom_adj”,作者推测“oom_adj”的值是根据软件在LRU列表中的位置所决定的;


    3.Android不同于Linux,有一套自己独特的进程管理模块,这个模块有更强的可定制性,可根据“oom_adj”值的范围来决定进程管理策略,比如可以设定当内存小于X时,结束“oom_adj”大于Y的进程。这给了进程管理脚本的编写以更多的选择。

    4.Android将进程分为六大类:

    1.前台进程(foreground目前正在屏幕上显示的进程和一些系统进程。举例来说,Dialer StorageGoogle Search等系统进程就是前台进程;再举例来说,当你运行一个程序,如浏览器,当浏览器界面在前台显示时,浏览器属于前台进程(foreground),但一旦你按home回到主界面,浏览器就变成了后台程序(background)。我们最不希望终止的进程就是前台进程。

    2.可见进程(visible:可见进程是一些不再前台,但用户依然可见的进程,举个例来说:widget、输入法等,都属于visible。这部分进程虽然不在前台,但与我们的使用也密切相关,我们也不希望它们被终止(你肯定不希望时钟、天气,新闻等widget被终止,那它们将无法同步,你也不希望输入法被终止,否则你每次输入时都需要重新启动输入法)

    3.次要服务(secondary server:目前正在运行的一些服务(主要服务,如拨号等,是不可能被进程管理终止的,故这里只谈次要服务),举例来说:谷歌企业套件,Gmail内部存储,联系人内部存储等。这部分服务虽然属于次要服务,但很一些系统功能依然息息相关,我们时常需要用到它们,所以也太希望他们被终止

    4.后台进程(hidden:虽然作者用了hidden这个词,但实际即是后台进程(background),就是我们通常意义上理解的启动后被切换到后台的进程,如浏览器,阅读器等。当程序显示在屏幕上时,他所运行的进程即为前台进程(foreground),一旦我们按home返回主界面(注意是按home,不是按back),程序就驻留在后台,成为后台进程
    background)。后台进程的管理策略有多种:有较为积极的方式,一旦程序到达后台立即终止,这种方式会提高程序的运行速度,但无法加速程序的再次启动;也有较消极的方式,尽可能多的保留后台程序,虽然可能会影响到单个程序的运行速度,但在再次启动已启动的程序时,速度会有所提升。这里就需要用户根据自己的使用习惯找到一个平衡点

    5.内容供应节点(content provider:没有程序实体,进提供内容供别的程序去用的,比如日历供应节点,邮件供应节点等。在终止进程时,这类程序应该有较高的优先权

    6.空进程(empty:没有任何东西在内运行的进程,有些程序,比如BTE,在程序退出后,依然会在进程中驻留一个空进程,这个进程里没有任何数据在运行,作用往往是提高该程序下次的启动速度或者记录程序的一些历史信息。这部分进程无疑是应该最先终止的。

    进程管理策略设置原则:
    前台进程、可见进程和次要服务是与用户体验息息相关的内容,这部分的进程管理策略要相对保守,给这些进程留下足够的运行空间
    压榨无用进程,腾出内存空间给主要程序使用

     

    展开全文
  • 某项目的应用服务器CPU和内存使用率的监控,通过zabbix系统监控记录应用服务器上进程的CPU和内存的使用情况,并以图表的形式实时展现,以便于我们分析服务器的性能瓶颈。 监控方式 利用zabbix监控系统的自动发现...

    监控需求

      某项目的应用服务器CPU和内存使用率的监控,通过zabbix系统监控记录应用服务器上进程的CPU和内存的使用情况,并以图表的形式实时展现,以便于我们分析服务器的性能瓶颈。

    监控方式

      利用zabbix监控系统的自动发现功能,首先编写shell脚本获取服务器的CPU和内存资源使用率最大的进程,以json的格式输出,然后对这些进程的CPU和内存资源使用情况进行监控。(本文监控的进程为Linux服务器中资源使用率最高的10个进程。)

     

    缺点

    不适用于监控固定的进程

     

    首先使用top命令查看进程状态,再取出进程的%CPU(该值表示单个CPU的进程从上次更新到现在的CPU时间占用百分比) 和%MEM值。

    hmracdb2:~ # top
    top - 13:57:01 up 32 days,  5:21,  2 users,  load average: 0.14, 0.26, 0.34
    Tasks: 206 total,   1 running, 205 sleeping,   0 stopped,   0 zombie
    Cpu(s):  3.7%us,  2.7%sy,  0.0%ni, 87.2%id,  6.3%wa,  0.0%hi,  0.1%si,  0.0%st
    Mem:   3926096k total,  3651612k used,   274484k free,   788120k buffers
    Swap:  4193276k total,  1369968k used,  2823308k free,  1443884k cached
     
      PID USER      PR  NI  VIRT  RES  SHR S   %CPU %MEM    TIME+  COMMAND                                                          
     2365 root      20   0  854m 315m  12m S      3  8.2   1252:49 ohasd.bin                                                         
     5307 oracle    20   0 1783m  22m  22m S      3  0.6   1106:03 oracle                                                            
     4532 root      20   0  676m  31m  13m S      2  0.8 853:35.32 crsd.bin                                                          
     4272 grid      RT   0  437m 282m  52m S      2  7.4   1006:47 ocssd.bin                                                         
     5279 oracle    20   0 1771m  60m  48m S      2  1.6 477:11.19 oracle                                                            
     5122 oracle    20   0  654m  15m  12m S      1  0.4 537:40.85 oraagent.bin

     

     

    由于top是交互的命令,我们把top命令的结果输出到一个文件上

    hmracdb2:~ # top -b -n 1 > /tmp/.top.txt

     

    第一个脚本,获取监控进程内存资源占有率前10的进程,输出格式为json格式,用于zabbix自动发现进程

    # cat discovery_process.sh 
    #!/bin/bash
    #system process discovery script
    top -b -n 1 > /tmp/.top.txt && chown zabbix. /tmp/.top.txt
    proc_array=(`tail -n +8 /tmp/.top.txt | awk '{a[$NF]+=$10}END{for(k in a)print a[k],k}'|sort -gr|head -10|cut -d" " -f2`)
    length=${#proc_array[@]}
     
    printf "{\n"
    printf '\t'"\"data\":["
    for ((i=0;i<$length;i++))
    do
        printf "\n\t\t{"
        printf "\"{#PROCESS_NAME}\":\"${proc_array[$i]}\"}"
        if [ $i -lt $[$length-1] ];then
            printf ","
        fi
    done
        printf "\n\t]\n"
    printf "}\n"

    或者

    # cat discovery_process2.sh 
    #!/bin/bash
    #system process discovery script
    top -b -n 1 > /tmp/.top.txt && chown zabbix. /tmp/.top.txt
    proc_array=`tail -n +8 /tmp/.top.txt | awk '{a[$NF]+=$10}END{for(k in a)print a[k],k}'|sort -gr|head -10|cut -d" " -f2`
     
    length=`echo "${proc_array}" | wc -l`
    count=0
    echo '{'
    echo -e '\t"data":['
    echo "$proc_array" | while read line
    do
        echo -en '\t\t{"{#PROCESS_NAME}":"'$line'"}'
        count=$(( $count + 1 ))
        if [ $count -lt $length ];then
            echo ','
        fi
    done
    echo -e '\n\t]'
    echo '}'

     

    输出的效果如下

    [root@Zabbix_19F ~]# ./discovery_process.sh 
    {
    "data":[
    {"{#PROCESS_NAME}":"mysqld"},
    {"{#PROCESS_NAME}":"php-fpm"},
    {"{#PROCESS_NAME}":"zabbix_server"},
    {"{#PROCESS_NAME}":"nginx"},
    {"{#PROCESS_NAME}":"sshd"},
    {"{#PROCESS_NAME}":"bash"},
    {"{#PROCESS_NAME}":"zabbix_agentd"},
    {"{#PROCESS_NAME}":"qmgr"},
    {"{#PROCESS_NAME}":"pickup"},
    {"{#PROCESS_NAME}":"master"}
    ]
    }

     

    第二个脚本,用于zabbix监控的具体监控项目(item)的key,通过脚本获取第一个脚本自动发现的进程的CPU和内存的具体使用情况与使用率。

    #!/bin/bash
    #system process CPU&MEM use information
    #mail: mail@huangming.org
    mode=$1
    name=$2
    process=$3
    mem_total=$(cat /proc/meminfo | grep "MemTotal" | awk '{printf "%.f",$2/1024}')
    cpu_total=$(( $(cat /proc/cpuinfo | grep "processor" | wc -l) * 100 ))
     
    function mempre {
        mem_pre=`tail -n +8 /tmp/.top.txt | awk '{a[$NF]+=$10}END{for(k in a)print a[k],k}' | grep "\b${process}\b" | cut -d" " -f1`
        echo "$mem_pre"
    }
     
    function memuse {
        mem_use=`tail -n +8 /tmp/.top.txt | awk '{a[$NF]+=$10}END{for(k in a)print a[k]/100*'''${mem_total}''',k}' | grep "\b${process}\b" | cut -d" " -f1`
        echo "$mem_use" | awk '{printf "%.f",$1*1024*1024}'
    }
     
    function cpuuse {
        cpu_use=`tail -n +8 /tmp/.top.txt | awk '{a[$NF]+=$9}END{for(k in a)print a[k],k}' | grep "\b${process}\b" | cut -d" " -f1`
        echo "$cpu_use"
    }
     
    function cpupre {
        cpu_pre=`tail -n +8 /tmp/.top.txt | awk '{a[$NF]+=$9}END{for(k in a)print a[k]/('''${cpu_total}'''),k}' | grep "\b${process}\b" | cut -d" " -f1`
        echo "$cpu_pre"
    }
     
     
    case $name in
        mem)
            if [ "$mode" = "pre" ];then
                mempre
            elif [ "$mode" = "avg" ];then
                memuse
            fi
        ;;
        cpu)
            if [ "$mode" = "pre" ];then
                cpupre
            elif [ "$mode" = "avg" ];then
                cpuuse
            fi
        ;;
        *)
            echo -e "Usage: $0 [mode : pre|avg] [mem|cpu] [process]"
    esac

     

    我们先来查看一下当前系统的内存和CPU大小情况:

    -- 内存
    [root@Zabbix_19F ~]# cat /proc/meminfo | grep "MemTotal" | awk '{printf "%.f",$2/1024}'
    3832
    -- CPU
    [root@Zabbix_19F ~]# cat /proc/cpuinfo | grep "processor" | wc -l
    8

     

    执行脚本运行效果如下(获取监控项key值)

    [root@Zabbix_19F ~]# ./process_check.sh avg mem mysqld   #输出mysqld进程使用的内存(计算公式:3832*18.5/100)
    708.92
    [root@Zabbix_19F ~]# ./process_check.sh pre mem mysqld   #输出mysqld进程内存的使用率
    18.5
    [root@Zabbix_19F ~]# ./process_check.sh avg cpu mysqld   #单个CPU的mysqld进程使用率
    3.9
    [root@Zabbix_19F ~]# ./process_check.sh pre cpu mysqld   #所有CPU的mysqld进程的使用率
    0.004875

     

    配置zabbix_agentd,在agentd客户端的etc/zabbix_agentd.conf中增加userparameter配置,增加进程自动发现的key,和进程资源检测的key。

    hmracdb2:/opt/zabbix # vim etc/zabbix_agentd.conf.d/userparameter_script.conf 
    UserParameter=discovery.process,/opt/zabbix/scripts/discovery_process.sh
    UserParameter=process.check[*],/opt/zabbix/scripts/process_check.sh $1 $2 $3

     

    配置完之后重启agentd服务

    hmracdb2:/opt/zabbix # service zabbix_agentd restart
    Shutting down zabbix_agentd                                                           done
    Starting zabbix_agentd                                                                done

    在zabbix服务器端手动获取监控项key值数据

    [root@Zabbix_19F ~]# zabbix_get -p10050 -k 'discovery.process' -s 10.xxx.xxx.xxx
    {
    "data":[
    {"{#PROCESS_NAME}":"ohasd.bin"},
    {"{#PROCESS_NAME}":"ocssd.bin"},
    {"{#PROCESS_NAME}":"oracle"},
    {"{#PROCESS_NAME}":"oraagent.bin"},
    {"{#PROCESS_NAME}":"crsd.bin"},
    {"{#PROCESS_NAME}":"orarootagent.bi"},
    {"{#PROCESS_NAME}":"watchdog/3"},
    {"{#PROCESS_NAME}":"watchdog/2"},
    {"{#PROCESS_NAME}":"watchdog/1"},
    {"{#PROCESS_NAME}":"watchdog/0"}
    ]
    }
     
    [root@Zabbix_19F ~]# zabbix_get -p10050 -k 'process.check[pre,mem,oracle]' -s 10.xxx.xxx.xxx
    2.9
    [root@Zabbix_19F ~]# zabbix_get -p10050 -k 'process.check[avg,mem,oracle]' -s 10..xxx.xxx.xxx
    111.186
    [root@Zabbix_19F ~]# zabbix_get -p10050 -k 'process.check[avg,cpu,oracle]' -s 10..xxx.xxx.xxx
    4
    [root@Zabbix_19F ~]# zabbix_get -p10050 -k 'process.check[pre,cpu,oracle]' -s 10..xxx.xxx.xxx
    0.01

     

    配置完agentd后,在zabbix服务器配置Web端的模版与监控项目item

    Configuration --> Templates --> Create template -->

    创建完模版之后,添加自动发现规则

    Discovery rules -->Create discovesy rule

     

     

    Item prototypes --> Create item prototype

     

    也可以继续添加监控的主机和所需监控项,添加完后我们可以查看下监控的历史数据

     

    添加一个进程的CPU使用率的监控项

     

    查看历史数据

     

    当然还可以获取进程内存使用的具体大小情况

     

       至此,zabbix自动发现进程内存和CPU使用情况并实时监控配置就完成了

    转载自HMLinux >>> 原帖http://blog.51cto.com/7424593/1908930

    展开全文
  • 根据前面的介绍,NT内核会把操作系统的代码和数据映射到系统中所有进程的内核空间中。这样,每个进程内的应用程序代码便可以很方便地调用内核空间中的系统服务。这里的“很方便”有多层含义,一方面是内核代码和用户...
  • 数字取证技术 :Windows内存信息提取

    千次阅读 2017-04-05 17:44:19
    数字取证技术 :Windows内存信息提取。后面会花一部分时间,写一些数字取证相关的文章。攻击技术贴多如牛毛,眼下不管是网安,还是安全厂商, 欠缺的是对取证技术的研究。 大致想了一下,主要会从以下几个方面逐一...
  • Python黑帽第一篇文章将分享获取Windows主机信息,利用注册表获取主机名及USB历史痕迹、回收站文件等,这些知识广泛应用于电子取证、Web渗透和攻击溯源领域,其中USB获取是亮点。希望这篇基础文章对您有所帮助,更...
  • 简介windows内存取证的内容概括起来讲就是检测系统中有没有恶意程序,有没有隐藏进程,有没有隐藏文件,有没有隐藏服务,有没有隐藏的驱动,有没有隐藏网络端口等等.而进程,文件,驱动等等部件在内存中是以内核对象的...
  • 推动Windows的限制:物理内存

    千次阅读 2018-01-31 21:26:11
    为了能够有效地管理Windows系统,您需要了解Windows如何管理物理资源(如CPU和内存)以及逻辑资源(如虚拟内存,句柄和窗口管理器对象)。了解这些资源的限制以及如何跟踪其使用情况,可以将资源使用情况归因于...
  • windows进程详解

    千次阅读 2011-11-18 08:14:35
    xp系统进程信息 系统进程 [system process] alg.exe csrss.exe ddhelp.exe dllhost.exe explorer.exe inetinfo.exe internat.exe kernel32.dll lsass.exe mdm.exe mmtask.tsk mprexe.exe msgsrv32.exe ...
  • 系统性能监控分析(Linux,Windows

    千次阅读 2021-12-21 10:49:22
    系统需要分配调度在它平台上的各类运行程序像它申请的资源,操作系统需要格局用户的需求来进行分配和调度,需要把内存,CPU,网络,磁盘等资源分配给对应的应用程序,以便让它执行,以及程序执行结束时回收它的资源...
  • 2.进程运行的基本原理 1. 指令的工作原理 2.逻辑地址vs物理地址 3.从写程序到程序运行 4.装入的三种方式 1.绝对装入 2. 可重定位装入(静态重定位) 3. 动态运行时装入(动态重定位) 5.链接的三种方式 1. 静态链接 ...
  • 怎么查看服务器上的所有进程

    千次阅读 2021-08-11 03:55:33
    这是由于Windows服务器的explorer.exe进程异常导致的。explorer.exe是Windows程序管理器或者文件资源管理器,它用于管理Windows图形壳,包括桌面和文件管理,删除该程序会导致Windows图形界面无法使用。打开云服在...
  • 内存取证-volattlity

    千次阅读 2020-09-30 14:33:34
    Volatility是开源的Windows,Linux,MaC,Android的内存取证分析工具,由python编写成,命令行操作,支持各种操作系统。 项目地址: https://code.google.com/archive/p/volatility/ 安装: kali-bt5自带此工具 $ ...
  • Linux进程概念(精讲)

    千次阅读 多人点赞 2021-09-09 08:54:04
    文章目录基本概念描述进程-PCB组织进程查看进程通过系统调用获取进程的PID和PPID通过系统调用创建进程- fork初始进程状态运行状态-R浅度睡眠状态-S深度睡眠状态-D暂停状态-T僵尸状态-Z死亡状态-X僵尸进程僵尸进程的...
  • 推动Windows的限制:虚拟内存

    千次阅读 2018-01-31 21:27:03
    在我推出Windows的限制后...推动Windows的限制:物理内存推动Windows的限制:虚拟内存推动Windows的限制:分页和非分页池推动Windows的限制:进程和线程推动Windows的限制:把手推动Windows的限制:USER和GDI对象 -...
  • Linux 进程必知必会

    千次阅读 2020-07-10 08:58:31
    系统调用是操作系统本身的接口,它对于创建进程和线程,内存分配,共享文件和 I/O 来说都很重要。 我们将从各个版本的共性出发来进行探讨。 基本概念 Linux 一个非常重要的概念就是进程,Linux 进程和我们在 进程和...
  • 操作系统中有虚拟内存与物理内存的概念。 首先理解一下什么叫物理内存?什么叫虚拟内存? 物理内存是指由于安装内存条而获得的临时储存空间。主要作用是在计算机运行时为操作系统和各种程序提供临时储存。常见的...
  • windows日志文件查看与清理

    千次阅读 2021-09-12 19:12:50
    (1) 启动Windows实验台,点击:开始 - 控制面板 - 管理工具 - 事件查看器。如下图所示。 (2) 应用程序日志、安全日志、系统日志、DNS日志默认位置:%sys temroot%\system32\config,默认文件大小512KB,管理员可以...
  • volatility内存取证

    千次阅读 2022-02-07 21:02:30
    find "chrome.exe" 可以列出所有chrome浏览器的进程,然后提取 常见Windows进程名 TrueCrypt.exe 磁盘加密工具notepad.exe 自带记事本mspaint.exe 自带画图工具iexplore.exe IE浏览器DumpIt.exe 内存镜像提取工具 ...
  • Android的内存进程调度管理 (二)

    千次阅读 2015-05-12 14:15:13
    安卓Android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知道java,就能更清楚这机制了.其实和java的垃圾回收机制类似,系统有一个规则来回收内存.进行内存调度有个阀值,只有低于这个...
  • 2016-12-04 12:10:30 1、简单的,可以打开游览器,打开查看菜单——游览器栏——历史记录——按站点,按日期,按访问顺序等,都可以查看出电脑上网情况。有的游览器,查看栏有我的电脑查看项。也可以查看使用电脑情...
  • 浅析Volatility内存取证

    2022-04-10 14:39:56
    浅析内存取证 volatility快速上手 Volatility是开源的Windows,Linux,Mac,Android的内存取证分析工具,由python编写成命令行操作,支持各种操作系统
  • Windows 取证

    千次阅读 2020-03-17 15:19:45
    易失性数据:主要存在于被入侵机器的寄存器、缓存、内存中。主要包括网络连接状态、正在运行的进程等信息。 一、Windows 中的一些易失性数据及获取 [系统环境变量] set [系统日期和时间] Date /t time /t [当前...
  • Python开发系列课程(16) - 进程和线程

    千次阅读 2018-03-27 19:10:58
    进程和线程 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务...
  • Windows手工入侵排查思路

    千次阅读 2021-04-14 00:36:54
    Windows系统被入侵后,通常会导致系统资源占用过高、异常端口和进程、可疑的账号或文件等,给业务系统带来不稳定等诸多问题。一些病毒木马会随着计算机启动而启动并获取一定的控制权,启动方式多...
  • 浅析内存取证

    千次阅读 2020-10-04 10:23:44
    在主机存活时发现系统被入侵,然后直接把机器的运行内存dump下来,对运行内存进行分析,还原一些进程的中的信息。 主要工作便是 抓取文件metadata 创建时间线 命令历史 分析日志文件 哈希摘要 转存内存信息等 什么...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,123
精华内容 12,049
关键字:

windows进程内存历史记录