声明:
找到服务器僵死的原因了,原因是虚拟内存设置小于物理内存.
只要虚拟内存设置为系统默认大小就不会出生僵死的现象了.
当时因为服务器内存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有任何疑问请联系:zwfgdlc@qq.com");
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;
}