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


    声明:

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

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

    当时因为服务器内存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("使用方法: SetSystemFileCache.exe 最小缓存限制 最大缓存限制 比如:SetSystemFileCache.exe 128 1024 即设置最小缓存为128MB, 最大缓存1024MB 刷新系统文件缓存: SetSystemFileCache.exe -flush 关闭系统文件缓存限制(系统默认): SetSystemFileCache.exe -disable 以服务方式运行: SetSystemFileCache.exe 128 1024 -Service 即设置最小缓存为128MB,最大缓存为1024MB并以服务方式运行. 当前系统文件缓存限制: 最小文件缓存:%uMB 最大文件缓存:%uMB 最小文件缓存开关状态: %s 最大文件缓存开关状态: %s "),   
      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("设置系统文件缓存大小上限成功! 当前设置: 最小缓存%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限制系统文件缓存工具 By zwfgdlc 有任何疑问请联系: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("创建服务失败! 服务已经存在,是否删除服务?"), 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

  • 相关阅读:
    基于MongoDB.Driver的扩展
    通用查询设计思想
    API接口通讯参数规范
    lambda简单记录
    list去重精简代码版
    spring boot file上传
    fastjson过滤器简单记录
    java读取properties文件
    list循环删除单个元素
    MapReduce运行流程分析
  • 原文地址:https://www.cnblogs.com/findumars/p/6344988.html
Copyright © 2020-2023  润新知