設定windows2008系統快取大小限制,解決伺服器執行久了因實體記憶體耗盡出僵死
阿新 • • 發佈:2019-01-10
宣告:
找到伺服器僵死的原因了,原因是虛擬記憶體設定小於實體記憶體.
只要虛擬記憶體設定為系統預設大小就不會出生僵死的現象了.
當時因為伺服器記憶體48G,系統預設虛擬記憶體大小也是48G,
覺得太佔硬碟空間,一時手賤,改小了虛擬記憶體,才會造成伺服器長時間執行僵死的現象.
#include <tchar.h> #include <stdio.h> #include <windows.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") #ifndef FILE_CACHE_FLAGS_DEFINED #define FILE_CACHE_MAX_HARD_ENABLE 0x00000001 #define FILE_CACHE_MAX_HARD_DISABLE 0x00000002 #define FILE_CACHE_MIN_HARD_ENABLE 0x00000004 #define FILE_CACHE_MIN_HARD_DISABLE 0x00000008 #endif LPTSTR lpSrvName = TEXT("SystemFileCacheLimit"); SERVICE_STATUS ServiceStatus = {0}; SERVICE_STATUS_HANDLE hStatus; BOOL WINAPI EnablePrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tkp; if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return( FALSE ); ::LookupPrivilegeValue(NULL, SE_INCREASE_QUOTA_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; ::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (::GetLastError() != ERROR_SUCCESS) return FALSE; return TRUE; } VOID WINAPI ServiceHandler(DWORD fdwControl) { switch(fdwControl) { case SERVICE_CONTROL_PAUSE: ServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: ServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; SetServiceStatus(hStatus,&ServiceStatus); return ; case SERVICE_CONTROL_INTERROGATE: break; default: break; } SetServiceStatus(hStatus,&ServiceStatus); return ; } VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { DWORD status = 0; DWORD specificError = 0xfffffff; ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; hStatus = RegisterServiceCtrlHandler(lpSrvName,(LPHANDLER_FUNCTION)ServiceHandler); if (hStatus==0) { return; } status = GetLastError(); if (status!=NO_ERROR) { ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; ServiceStatus.dwWin32ExitCode = status; ServiceStatus.dwServiceSpecificExitCode = specificError; SetServiceStatus(hStatus, &ServiceStatus); return; } ServiceStatus.dwCurrentState = SERVICE_RUNNING; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; SetServiceStatus(hStatus, &ServiceStatus); ULONG MiniCache, MaxCache; TCHAR szIni[MAX_PATH] = {0}; ::GetModuleFileName(NULL, szIni, _countof(szIni)); ::PathRenameExtension(szIni, TEXT(".ini")); if (dwArgc >=4) { ::WritePrivateProfileString(TEXT("引數設定"), TEXT("最大快取"), lpszArgv[3], szIni); ::WritePrivateProfileString(TEXT("引數設定"), TEXT("最小快取"), lpszArgv[2], szIni); MiniCache = _ttol(lpszArgv[2]) * 1024 * 1024; MaxCache = _ttol(lpszArgv[3]) * 1024 * 1024; } else { if (PathFileExists(szIni)) { MiniCache = ::GetPrivateProfileInt(TEXT("引數設定"), TEXT("最小快取"), -1, szIni); MaxCache = ::GetPrivateProfileInt(TEXT("引數設定"), TEXT("最大快取"), -1, szIni); MiniCache = MiniCache * 1024 * 1024; MaxCache = MaxCache * 1024 * 1024; } } EnablePrivileges(); ::SetSystemFileCacheSize(MiniCache, MaxCache, FILE_CACHE_MAX_HARD_ENABLE|FILE_CACHE_MIN_HARD_ENABLE); return; } int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nShowCmd) { SIZE_T MiniCache, MaxCache; DWORD dwFlags; TCHAR szMsg[512] = {0}; LPWSTR* szArgList; int nArgs; if (!::FindWindow(TEXT("Progman"), NULL)) { SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = lpSrvName; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; StartServiceCtrlDispatcher(ServiceTable); return 1; } szArgList = ::CommandLineToArgvW(::GetCommandLineW(), &nArgs); switch(nArgs) { case 1: ::GetSystemFileCacheSize(&MiniCache, &MaxCache, &dwFlags); _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"), MiniCache/1024/1024, MaxCache/1024/1024, dwFlags&FILE_CACHE_MIN_HARD_ENABLE ? TEXT("開啟") : TEXT("關閉"), dwFlags&FILE_CACHE_MAX_HARD_ENABLE ? TEXT("開啟") : TEXT("關閉")); ::MessageBox(::GetDesktopWindow(), szMsg, TEXT("提示"), MB_ICONASTERISK); break; case 2: EnablePrivileges(); if (_tcsicmp(szArgList[1], TEXT("-flush")) == 0) { if (::SetSystemFileCacheSize(-1, -1, FILE_CACHE_MAX_HARD_ENABLE|FILE_CACHE_MIN_HARD_ENABLE)) { ::MessageBox(GetDesktopWindow(), TEXT("刷新系統檔案快取成功!"), TEXT("提示"), MB_ICONASTERISK); }else { ::MessageBox(GetDesktopWindow(), TEXT("刷新系統檔案快取失敗!"), TEXT("提示"), MB_ICONASTERISK); } } else if(_tcsicmp(szArgList[1], TEXT("-disable")) == 0) { if (::SetSystemFileCacheSize(0, 0, FILE_CACHE_MAX_HARD_DISABLE|FILE_CACHE_MIN_HARD_DISABLE)) { ::MessageBox(GetDesktopWindow(), TEXT("已成功關閉系統檔案快取大小限制!"), TEXT("提示"), MB_ICONASTERISK); }else { ::MessageBox(GetDesktopWindow(), TEXT("關閉系統檔案快取大小限制失敗!"), TEXT("提示"), MB_ICONASTERISK); } } break; case 3: MiniCache = _ttol(szArgList[1])*1024*1024; MaxCache = _ttol(szArgList[2])*1024*1024; EnablePrivileges(); if (::SetSystemFileCacheSize(MiniCache, MaxCache, FILE_CACHE_MAX_HARD_ENABLE|FILE_CACHE_MIN_HARD_ENABLE)) { _stprintf_s(szMsg, _countof(szMsg), TEXT("設定系統檔案快取大小上限成功!\n\n當前設定: 最小快取%dMB, 最大快取%dMB"), MiniCache/1024/1024, MaxCache/1024/1024); ::MessageBox(GetDesktopWindow(), szMsg, TEXT("提示"), MB_ICONASTERISK); } else { ::MessageBox(GetDesktopWindow(), TEXT("設定系統檔案快取大小上限失敗!"), TEXT("提示"), MB_ICONASTERISK); } break; case 4: if (_tcsicmp(szArgList[3], TEXT("-Service")) == 0) { TCHAR szPath[MAX_PATH] = {0}; SERVICE_DESCRIPTION SrvDesc; SrvDesc.lpDescription = TEXT("Windows2008限制系統檔案快取工具\r\nBy zwfgdlc\r\n有任何疑問請聯絡:
[email protected]"); SC_HANDLE hScm = ::OpenSCManager(NULL, NULL, GENERIC_READ | GENERIC_WRITE); ::GetModuleFileName(NULL, szPath, _countof(szPath)); if (hScm) { 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); if (hService == NULL && ::GetLastError() == ERROR_SERVICE_EXISTS) { if (IDYES == ::MessageBox(GetDesktopWindow(), TEXT("建立服務失敗!\n服務已經存在,是否刪除服務?"), TEXT("警告"), MB_ICONWARNING|MB_YESNO)) { hService = ::OpenService(hScm, lpSrvName, DELETE); if (hService!=NULL && ::DeleteService(hService)) { ::MessageBox(GetDesktopWindow(), TEXT("服務已刪除!"), TEXT("提示"), MB_ICONASTERISK); } ::CloseServiceHandle(hService); } ::CloseServiceHandle(hScm); } else { ::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &SrvDesc); if (IDYES == ::MessageBox(GetDesktopWindow(), TEXT("服務建立成功,是否立即啟動服務?"), TEXT("提示"), MB_ICONASTERISK|MB_YESNO)) { ::StartService(hService, nArgs, (LPCTSTR*)szArgList); } ::CloseServiceHandle(hService); ::CloseServiceHandle(hScm); } } } break; default: ::MessageBox(GetDesktopWindow(), TEXT("引數不正確!"), TEXT("提示"), MB_ICONWARNING); break; } LocalFree(szArgList); return 1; }