首页 > Windows开发 > 详细

设置windows2008系统缓存大小限制,解决服务器运行久了因物理内存耗尽出僵死(提升权限后,使用SetSystemFileCacheSize API函数,并将此做成了一个Service)

时间:2017-01-23 22:47:27      阅读:1931      评论:0      收藏:0      [点我收藏+]

声明:

找到服务器僵死的原因了,原因是虚拟内存设置小于物理内存.

只要虚拟内存设置为系统默认大小就不会出生僵死的现象了.

当时因为服务器内存48G,系统默认虚拟内存大小也是48G,

觉得太占硬盘空间,一时手贱,改小了虚拟内存,才会造成服务器长时间运行僵死的现象.

[cpp] view plain copy
 
    1. #include <tchar.h>  
    2. #include <stdio.h>  
    3. #include <windows.h>  
    4. #include <shlwapi.h>  
    5.   
    6. #pragma comment(lib, "shlwapi.lib")  
    7.   
    8. #ifndef FILE_CACHE_FLAGS_DEFINED  
    9.   
    10. #define FILE_CACHE_MAX_HARD_ENABLE      0x00000001  
    11. #define FILE_CACHE_MAX_HARD_DISABLE     0x00000002  
    12. #define FILE_CACHE_MIN_HARD_ENABLE      0x00000004  
    13. #define FILE_CACHE_MIN_HARD_DISABLE     0x00000008  
    14.   
    15. #endif  
    16.   
    17. LPTSTR lpSrvName = TEXT("SystemFileCacheLimit");  
    18. SERVICE_STATUS ServiceStatus = {0};  
    19. SERVICE_STATUS_HANDLE hStatus;  
    20.   
    21. BOOL WINAPI EnablePrivileges()  
    22. {  
    23.     HANDLE hToken;   
    24.     TOKEN_PRIVILEGES tkp;   
    25.   
    26.     if (!::OpenProcessToken(::GetCurrentProcess(),   
    27.         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))   
    28.         return( FALSE );   
    29.   
    30.     ::LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME,   
    31.         &tkp.Privileges[0].Luid);   
    32.   
    33.     tkp.PrivilegeCount = 1;   
    34.     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
    35.   
    36.     ::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,   
    37.         (PTOKEN_PRIVILEGES)NULL, 0);   
    38.   
    39.     if (::GetLastError() != ERROR_SUCCESS)   
    40.         return FALSE;   
    41.   
    42.     return TRUE;  
    43. }  
    44.   
    45. VOID WINAPI ServiceHandler(DWORD fdwControl)  
    46. {  
    47.     switch(fdwControl)  
    48.     {  
    49.     case SERVICE_CONTROL_PAUSE:  
    50.         ServiceStatus.dwCurrentState = SERVICE_PAUSED;  
    51.         break;  
    52.     case SERVICE_CONTROL_CONTINUE:  
    53.         ServiceStatus.dwCurrentState = SERVICE_RUNNING;  
    54.         break;  
    55.     case SERVICE_CONTROL_STOP:  
    56.     case SERVICE_CONTROL_SHUTDOWN:  
    57.         ServiceStatus.dwCurrentState  = SERVICE_STOPPED;  
    58.         ServiceStatus.dwWin32ExitCode = 0;  
    59.         ServiceStatus.dwCheckPoint    = 0;  
    60.         ServiceStatus.dwWaitHint      = 0;  
    61.         SetServiceStatus(hStatus,&ServiceStatus);  
    62.         return ;  
    63.     case SERVICE_CONTROL_INTERROGATE:  
    64.         break;  
    65.     default:  
    66.         break;  
    67.     }  
    68.     SetServiceStatus(hStatus,&ServiceStatus);  
    69.     return ;  
    70. }  
    71.   
    72.   
    73.   
    74. VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)  
    75. {  
    76.     DWORD   status = 0;  
    77.     DWORD   specificError = 0xfffffff;  
    78.     ServiceStatus.dwServiceType        = SERVICE_WIN32;  
    79.     ServiceStatus.dwCurrentState       = SERVICE_START_PENDING;  
    80.     ServiceStatus.dwControlsAccepted   =  SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;  
    81.     ServiceStatus.dwWin32ExitCode      = 0;  
    82.     ServiceStatus.dwServiceSpecificExitCode = 0;  
    83.     ServiceStatus.dwCheckPoint         = 0;  
    84.     ServiceStatus.dwWaitHint           = 0;  
    85.   
    86.     hStatus = RegisterServiceCtrlHandler(lpSrvName,(LPHANDLER_FUNCTION)ServiceHandler);  
    87.     if (hStatus==0)  
    88.     {  
    89.         return;  
    90.     }  
    91.   
    92.     status = GetLastError();  
    93.     if (status!=NO_ERROR)  
    94.     {  
    95.         ServiceStatus.dwCurrentState       = SERVICE_STOPPED;  
    96.         ServiceStatus.dwCheckPoint         = 0;  
    97.         ServiceStatus.dwWaitHint           = 0;  
    98.         ServiceStatus.dwWin32ExitCode      = status;  
    99.         ServiceStatus.dwServiceSpecificExitCode = specificError;  
    100.         SetServiceStatus(hStatus, &ServiceStatus);  
    101.           
    102.         return;  
    103.     }  
    104.   
    105.     ServiceStatus.dwCurrentState       = SERVICE_RUNNING;  
    106.     ServiceStatus.dwCheckPoint         = 0;  
    107.     ServiceStatus.dwWaitHint           = 0;    
    108.     SetServiceStatus(hStatus, &ServiceStatus);    
    109.       
    110.     ULONG MiniCache, MaxCache;  
    111.     TCHAR szIni[MAX_PATH] = {0};  
    112.   
    113.     ::GetModuleFileName(NULL, szIni, _countof(szIni));  
    114.     ::PathRenameExtension(szIni, TEXT(".ini"));  
    115.       
    116.     if (dwArgc >=4)  
    117.     {  
    118.         ::WritePrivateProfileString(TEXT("参数设置"), TEXT("最大缓存"), lpszArgv[3], szIni);  
    119.         ::WritePrivateProfileString(TEXT("参数设置"), TEXT("最小缓存"), lpszArgv[2], szIni);  
    120.         MiniCache = _ttol(lpszArgv[2]) * 1024 * 1024;  
    121.         MaxCache = _ttol(lpszArgv[3]) * 1024 * 1024;  
    122.     }  
    123.     else  
    124.     {  
    125.         if (PathFileExists(szIni))  
    126.         {  
    127.             MiniCache = ::GetPrivateProfileInt(TEXT("参数设置"), TEXT("最小缓存"), -1, szIni);  
    128.             MaxCache = ::GetPrivateProfileInt(TEXT("参数设置"), TEXT("最大缓存"), -1, szIni);  
    129.             MiniCache = MiniCache * 1024 * 1024;  
    130.             MaxCache = MaxCache * 1024 * 1024;  
    131.         }     
    132.     }  
    133.   
    134.     EnablePrivileges();  
    135.     ::SetSystemFileCacheSize(MiniCache, MaxCache, FILE_CACHE_MAX_HARD_ENABLE|FILE_CACHE_MIN_HARD_ENABLE);  
    136.   
    137.     return;  
    138. }  
    139.   
    140.   
    141. int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nShowCmd)  
    142. {  
    143.     SIZE_T MiniCache, MaxCache;  
    144.     DWORD dwFlags;  
    145.     TCHAR szMsg[512] = {0};  
    146.     LPWSTR* szArgList;  
    147.     int nArgs;  
    148.       
    149.     if (!::FindWindow(TEXT("Progman"), NULL))  
    150.     {  
    151.         SERVICE_TABLE_ENTRY ServiceTable[2];  
    152.         ServiceTable[0].lpServiceName = lpSrvName;  
    153.         ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;  
    154.         ServiceTable[1].lpServiceName = NULL;  
    155.         ServiceTable[1].lpServiceProc = NULL;  
    156.   
    157.         StartServiceCtrlDispatcher(ServiceTable);  
    158.         return 1;  
    159.     }  
    160.   
    161.     szArgList = ::CommandLineToArgvW(::GetCommandLineW(), &nArgs);  
    162.     switch(nArgs)  
    163.     {  
    164.     case 1:  
    165.         ::GetSystemFileCacheSize(&MiniCache, &MaxCache, &dwFlags);  
    166.         _stprintf_s(szMsg, _countof(szMsg), TEXT("使用方法:\n\nSetSystemFileCache.exe 最小缓存限制 最大缓存限制\n比如:SetSystemFileCache.exe 128 1024\n即设置最小缓存为128MB, 最大缓存1024MB\n\n刷新系统文件缓存: SetSystemFileCache.exe -flush\n\n关闭系统文件缓存限制(系统默认):\nSetSystemFileCache.exe -disable\n\n以服务方式运行:\nSetSystemFileCache.exe 128 1024 -Service\n即设置最小缓存为128MB,最大缓存为1024MB并以服务方式运行.\n\n当前系统文件缓存限制:\n最小文件缓存:%uMB\n最大文件缓存:%uMB\n最小文件缓存开关状态: %s\n最大文件缓存开关状态: %s\n"),   
    167.             MiniCache/1024/1024, MaxCache/1024/1024,   
    168.             dwFlags&FILE_CACHE_MIN_HARD_ENABLE ? TEXT("开启") : TEXT("关闭"),   
    169.             dwFlags&FILE_CACHE_MAX_HARD_ENABLE ? TEXT("开启") : TEXT("关闭"));  
    170.         ::MessageBox(::GetDesktopWindow(), szMsg, TEXT("提示"), MB_ICONASTERISK);  
    171.         break;  
    172.     case 2:  
    173.         EnablePrivileges();  
    174.         if (_tcsicmp(szArgList[1], TEXT("-flush")) == 0)  
    175.         {  
    176.             if (::SetSystemFileCacheSize(-1, -1, FILE_CACHE_MAX_HARD_ENABLE|FILE_CACHE_MIN_HARD_ENABLE))  
    177.             {  
    178.                 ::MessageBox(GetDesktopWindow(), TEXT("刷新系统文件缓存成功!"), TEXT("提示"), MB_ICONASTERISK);  
    179.             }else  
    180.             {  
    181.                 ::MessageBox(GetDesktopWindow(), TEXT("刷新系统文件缓存失败!"), TEXT("提示"), MB_ICONASTERISK);  
    182.             }  
    183.         }  
    184.         else if(_tcsicmp(szArgList[1], TEXT("-disable")) == 0)  
    185.         {  
    186.             if (::SetSystemFileCacheSize(0, 0, FILE_CACHE_MAX_HARD_DISABLE|FILE_CACHE_MIN_HARD_DISABLE))  
    187.             {  
    188.                 ::MessageBox(GetDesktopWindow(), TEXT("已成功关闭系统文件缓存大小限制!"), TEXT("提示"), MB_ICONASTERISK);  
    189.             }else  
    190.             {  
    191.                 ::MessageBox(GetDesktopWindow(), TEXT("关闭系统文件缓存大小限制失败!"), TEXT("提示"), MB_ICONASTERISK);  
    192.             }  
    193.         }  
    194.         break;  
    195.     case 3:  
    196.         MiniCache = _ttol(szArgList[1])*1024*1024;  
    197.         MaxCache = _ttol(szArgList[2])*1024*1024;  
    198.         EnablePrivileges();  
    199.           
    200.         if (::SetSystemFileCacheSize(MiniCache, MaxCache, FILE_CACHE_MAX_HARD_ENABLE|FILE_CACHE_MIN_HARD_ENABLE))  
    201.         {  
    202.             _stprintf_s(szMsg, _countof(szMsg), TEXT("设置系统文件缓存大小上限成功!\n\n当前设置: 最小缓存%dMB, 最大缓存%dMB"), MiniCache/1024/1024, MaxCache/1024/1024);  
    203.             ::MessageBox(GetDesktopWindow(), szMsg, TEXT("提示"), MB_ICONASTERISK);  
    204.         }  
    205.         else  
    206.         {  
    207.             ::MessageBox(GetDesktopWindow(), TEXT("设置系统文件缓存大小上限失败!"), TEXT("提示"), MB_ICONASTERISK);  
    208.         }  
    209.           
    210.         break;  
    211.     case 4:  
    212.         if (_tcsicmp(szArgList[3], TEXT("-Service")) == 0)  
    213.         {  
    214.             TCHAR szPath[MAX_PATH] = {0};  
    215.             SERVICE_DESCRIPTION SrvDesc;  
    216.             SrvDesc.lpDescription = TEXT("Windows2008限制系统文件缓存工具\r\nBy zwfgdlc\r\n有任何疑问请联系:zwfgdlc@qq.com");  
    217.               
    218.             SC_HANDLE hScm = ::OpenSCManager(NULL, NULL, GENERIC_READ | GENERIC_WRITE);  
    219.             ::GetModuleFileName(NULL, szPath, _countof(szPath));  
    220.               
    221.             if (hScm)  
    222.             {  
    223.                 SC_HANDLE hService = ::CreateService(hScm, lpSrvName, TEXT("SetSystemFileCache"), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);  
    224.                 if (hService == NULL && ::GetLastError() == ERROR_SERVICE_EXISTS)  
    225.                 {  
    226.                     if (IDYES == ::MessageBox(GetDesktopWindow(), TEXT("创建服务失败!\n服务已经存在,是否删除服务?"), TEXT("警告"), MB_ICONWARNING|MB_YESNO))  
    227.                     {  
    228.                         hService = ::OpenService(hScm, lpSrvName, DELETE);  
    229.                         if (hService!=NULL && ::DeleteService(hService))  
    230.                         {  
    231.                             ::MessageBox(GetDesktopWindow(), TEXT("服务已删除!"), TEXT("提示"), MB_ICONASTERISK);  
    232.                         }  
    233.                         ::CloseServiceHandle(hService);  
    234.                     }  
    235.                     ::CloseServiceHandle(hScm);  
    236.                 }  
    237.                 else  
    238.                 {  
    239.                     ::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &SrvDesc);  
    240.                     if (IDYES == ::MessageBox(GetDesktopWindow(), TEXT("服务创建成功,是否立即启动服务?"), TEXT("提示"), MB_ICONASTERISK|MB_YESNO))  
    241.                     {  
    242.                         ::StartService(hService, nArgs, (LPCTSTR*)szArgList);  
    243.                     }  
    244.                     ::CloseServiceHandle(hService);  
    245.                     ::CloseServiceHandle(hScm);  
    246.                 }  
    247.                   
    248.             }  
    249.         }  
    250.           
    251.         break;  
    252.     default:  
    253.         ::MessageBox(GetDesktopWindow(), TEXT("参数不正确!"), TEXT("提示"), MB_ICONWARNING);  
    254.         break;  
    255.     }  
    256.   
    257.     LocalFree(szArgList);  
    258.     return 1;  
    259. }  

 

http://blog.csdn.net/zwfgdlc/article/details/6403006

设置windows2008系统缓存大小限制,解决服务器运行久了因物理内存耗尽出僵死(提升权限后,使用SetSystemFileCacheSize API函数,并将此做成了一个Service)

原文:http://www.cnblogs.com/findumars/p/6344988.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!