Пример #1
0
void PrintMemInfo(int id){
	
	LPBYTE currAddress = 0;
	PSAPI_WORKING_SET_INFORMATION wsi;
	PSAPI_WORKING_SET_BLOCK* wsb;
	PERFORMANCE_INFORMATION pi;
	MEMORYSTATUSEX ms;
	PROCESS_MEMORY_COUNTERS pmc;
	PROCESS_MEMORY_COUNTERS_EX pmcex;
	DWORD countPrivatePages = 0;
	MEMORY_BASIC_INFORMATION mbi;
	LPBYTE regionNonFree = 0;

	ms.dwLength = sizeof (ms);

	_tprintf(_T("Informacao do sistema\n"));
	GetPerformanceInfo(&pi , sizeof(PERFORMANCE_INFORMATION));
	_tprintf(_T("\nTotal Memoria existente fisica em paginas->%d\n"),pi.PhysicalTotal);
	_tprintf(_T("Total Memoria ocupada fisica em paginas->%d\n"), (pi.PhysicalTotal - pi.PhysicalAvailable));
	
	GlobalMemoryStatusEx(&ms);
	_tprintf(_T("Total Memoria existente virtual em kb->%d\n"),ms.ullTotalPageFile / 1024);
	_tprintf(_T("Total Memoria ocupada virtual em kb->%d\n"),(ms.ullTotalPageFile - ms.ullAvailVirtual) / 1024);

	_tprintf(_T("\nInformacao do processo\n"));
	HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, id );
	
	if(!hProcess)
		return ;

	QueryWorkingSet(hProcess,&wsi,sizeof(wsi));
	wsb = wsi.WorkingSetInfo;

	_tprintf(_T("Dimensão do working set ->%d\n"),sizeof(wsb)*wsi.NumberOfEntries);
	
	GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc));
	_tprintf(_T("Page fault count ->%d\n"),pmc.PageFaultCount);
		
	while (VirtualQueryEx( hProcess,  currAddress, &mbi, sizeof(mbi)) > 0) {
		if (mbi.State != MEM_FREE)
			regionNonFree += mbi.RegionSize;
		
		currAddress += mbi.RegionSize;
	}
	_tprintf(_T("Total de espaço de endereçamento existente->%d\n"),currAddress-hProcess);
	_tprintf(_T("Total de espaço de endereçamento ocupado ->%d\n"),regionNonFree);

	for(int i = 0 ; i<sizeof(wsi) ; ++i){
		if(!(wsb+i)->Shared){
			countPrivatePages++;
		}
	}
	_tprintf(_T("Total de private pages->%d\n"),countPrivatePages);
}
Пример #2
0
void CWorkingSetMonitor::SampleWorkingSets()
{
	CSingleLock locker(&processesLock_);
	if (processes_.empty() && !processAll_)
		return;

	// CreateToolhelp32Snapshot runs faster than EnumProcesses and
	// it returns the process name as well, thus avoiding a call to
	// EnumProcessModules to get the name.
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, TH32CS_SNAPPROCESS);
	if (!hSnapshot)
		return;

	PROCESSENTRY32W peInfo;
	peInfo.dwSize = sizeof(peInfo);
	BOOL nextProcess = Process32First(hSnapshot, &peInfo);

	// Allocate enough space to get the working set of most processes.
	// It will grow if needed.
	ULONG_PTR numEntries = 100000;

	const rsize_t bufferSizeNeeded =
		sizeof(PSAPI_WORKING_SET_INFORMATION) +
		(numEntries * sizeof(PSAPI_WORKING_SET_BLOCK));

	std::vector<char> buffer(bufferSizeNeeded);
	PSAPI_WORKING_SET_INFORMATION* pwsBuffer = reinterpret_cast<PSAPI_WORKING_SET_INFORMATION*>(buffer.data());

	ULONG_PTR totalWSPages = 0;
	// The PSS page count is stored as a multiple of PSSMultiplier.
	// This allows all the supported share counts, from 1 to 7, to be
	// divided out without loss of precision. That is, an unshared page
	// is recorded by adding 420. A page shared by seven processes (the
	// maximum recorded) is recorded by adding 420/7.
	const uint64_t PSSMultiplier = 420; // LCM of 1, 2, 3, 4, 5, 6, 7
	uint64_t totalPSSPages = 0;
	ULONG_PTR totalPrivateWSPages = 0;

	// Iterate through the processes.
	while (nextProcess)
	{
		bool match = processAll_;
		for (const auto& name : processes_)
		{
			if (_wcsicmp(peInfo.szExeFile, name.c_str()) == 0)
			{
				match = true;
			}
		}
		if (match)
		{
			DWORD pid = peInfo.th32ProcessID;
			// Get a handle to the process.
			HANDLE hProcess =
				OpenProcess(PROCESS_QUERY_INFORMATION |
				PROCESS_VM_READ, FALSE, pid);
			ULONG_PTR wsPages = 0;
			uint64_t PSSPages = 0;
			ULONG_PTR privateWSPages = 0;

			if (NULL != hProcess)
			{
				bool success = true;
				if (bExpensiveWSMonitoring_)
				{
					if (!QueryWorkingSet(hProcess, &buffer[0], static_cast<DWORD>(buffer.size())))
					{
						success = false;
						// Increase the buffer size based on the NumberOfEntries returned,
						// with some padding in case the working set is increasing.
						if (GetLastError() == ERROR_BAD_LENGTH)
						{
							numEntries = pwsBuffer->NumberOfEntries + pwsBuffer->NumberOfEntries / 4;
							buffer.resize(sizeof(PSAPI_WORKING_SET_INFORMATION) + numEntries * sizeof(PSAPI_WORKING_SET_BLOCK));
							pwsBuffer = reinterpret_cast<PSAPI_WORKING_SET_INFORMATION*>(&buffer[0]);
							if (QueryWorkingSet(hProcess, &buffer[0], static_cast<DWORD>(buffer.size())))
							{
								success = true;
							}
						}
					}

					if (success)
					{
						wsPages = pwsBuffer->NumberOfEntries;
						for (ULONG_PTR page = 0; page < wsPages; ++page)
						{
							if (!pwsBuffer->WorkingSetInfo[page].Shared)
							{
								++privateWSPages;
								PSSPages += PSSMultiplier;
							}
							else
							{
								UIETWASSERT(pwsBuffer->WorkingSetInfo[page].ShareCount <= 7);
								PSSPages += PSSMultiplier / pwsBuffer->WorkingSetInfo[page].ShareCount;
							}
						}
						totalPSSPages += PSSPages;
						totalPrivateWSPages += privateWSPages;
					}
				}
				else
				{
					PROCESS_MEMORY_COUNTERS memoryCounters = {sizeof(memoryCounters)};
					if (GetProcessMemoryInfo(hProcess, &memoryCounters, sizeof(memoryCounters)))
					{
						wsPages = memoryCounters.WorkingSetSize / 4096;
					}
				}
				if (success)
				{
					totalWSPages += wsPages;

					wchar_t process[MAX_PATH + 100];
					swprintf_s(process, L"%s (%u)", peInfo.szExeFile, pid);
					ETWMarkWorkingSet(peInfo.szExeFile, process, counter_, static_cast<unsigned>(privateWSPages * 4), static_cast<unsigned>((PSSPages * 4) / PSSMultiplier), static_cast<unsigned>((wsPages * 4)));
				}

				CloseHandle(hProcess);
			}
		}
		nextProcess = Process32Next(hSnapshot, &peInfo);
	}
	CloseHandle(hSnapshot);

	ETWMarkWorkingSet(L"Total", L"", counter_, static_cast<unsigned>(totalPrivateWSPages * 4), static_cast<unsigned>((totalPSSPages * 4) / PSSMultiplier), static_cast<unsigned>(totalWSPages * 4));
	++counter_;
}
Пример #3
0
NTSTATUS PHAPI PhQueryProcessWs(
    HANDLE ProcessHandle,
    WS_INFORMATION_CLASS WsInformationClass,
    PVOID WsInformation,
    ULONG WsInformationLength,
    PULONG ReturnLength
    )
{
    switch (WsInformationClass)
    {
    case WsCount:
    case WsPrivateCount:
    case WsSharedCount:
    case WsShareableCount:
        if (WsInformationLength < 4)
            return STATUS_BUFFER_TOO_SMALL;
        goto WsCounters;
    case WsAllCounts:
        if (WsInformationLength < sizeof(WS_ALL_COUNTS))
            return STATUS_BUFFER_TOO_SMALL;
WsCounters:
        {
            PROCESS_MEMORY_COUNTERS procMem;
            ULONG count = 0;
            ULONG privateCount = 0;
            ULONG sharedCount = 0;
            ULONG shareableCount = 0;
            PPSAPI_WORKING_SET_INFORMATION wsInfo;
            SIZE_T wsInfoLength;
            ULONG i;

            if (!GetProcessMemoryInfo(ProcessHandle, &procMem, sizeof(procMem)))
                return STATUS_UNSUCCESSFUL;

            /* Assume the page size is 4kB */
            wsInfoLength = sizeof(PSAPI_WORKING_SET_INFORMATION) + 
                sizeof(PSAPI_WORKING_SET_BLOCK) * (procMem.WorkingSetSize / 4096);
            wsInfo = (PPSAPI_WORKING_SET_INFORMATION)PhAlloc(wsInfoLength);

            if (!QueryWorkingSet(ProcessHandle, wsInfo, wsInfoLength))
            {
                PhFree(wsInfo);
                return STATUS_UNSUCCESSFUL;
            }

            for (i = 0; i < wsInfo->NumberOfEntries; i++)
            {
                PSAPI_WORKING_SET_BLOCK block = wsInfo->WorkingSetInfo[i];

                count++;

                if (block.ShareCount > 1)
                    sharedCount++;
                if (block.ShareCount == 0)
                    privateCount++;
                if (block.Shared)
                    shareableCount++;
            }

            PhFree(wsInfo);

            switch (WsInformationClass)
            {
            case WsCount:
                *(PULONG)WsInformation = count;
                break;
            case WsPrivateCount:
                *(PULONG)WsInformation = privateCount;
                break;
            case WsSharedCount:
                *(PULONG)WsInformation = sharedCount;
                break;
            case WsShareableCount:
                *(PULONG)WsInformation = shareableCount;
                break;
            case WsAllCounts:
                {
                    PWS_ALL_COUNTS allCounts = (PWS_ALL_COUNTS)WsInformation;

                    allCounts->Count = count;
                    allCounts->PrivateCount = privateCount;
                    allCounts->SharedCount = sharedCount;
                    allCounts->ShareableCount = shareableCount;
                    break;
                }
            }

            return STATUS_SUCCESS;
        }
        break;
    default: 
        return STATUS_INVALID_PARAMETER;
    }
}
Пример #4
0
	bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
		size_t ws_private = 0;
		size_t ws_shareable = 0;
		size_t ws_shared = 0;

		DCHECK(ws_usage);
		memset(ws_usage, 0, sizeof(*ws_usage));

		DWORD number_of_entries = 4096;  // Just a guess.
		PSAPI_WORKING_SET_INFORMATION* buffer = NULL;
		int retries = 5;
		for (;;) {
			DWORD buffer_size = sizeof(PSAPI_WORKING_SET_INFORMATION) +
				(number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK));

			// if we can't expand the buffer, don't leak the previous
			// contents or pass a NULL pointer to QueryWorkingSet
			PSAPI_WORKING_SET_INFORMATION* new_buffer =
				reinterpret_cast<PSAPI_WORKING_SET_INFORMATION*>(
				realloc(buffer, buffer_size));
			if (!new_buffer) {
				free(buffer);
				return false;
			}
			buffer = new_buffer;

			// Call the function once to get number of items
			if (QueryWorkingSet(process_, buffer, buffer_size))
				break;  // Success

			if (GetLastError() != ERROR_BAD_LENGTH) {
				free(buffer);
				return false;
			}

			number_of_entries = static_cast<DWORD>(buffer->NumberOfEntries);

			// Maybe some entries are being added right now. Increase the buffer to
			// take that into account.
			number_of_entries = static_cast<DWORD>(number_of_entries * 1.25);

			if (--retries == 0) {
				free(buffer);  // If we're looping, eventually fail.
				return false;
			}
		}

		// On windows 2000 the function returns 1 even when the buffer is too small.
		// The number of entries that we are going to parse is the minimum between the
		// size we allocated and the real number of entries.
		number_of_entries =
			std::min(number_of_entries, static_cast<DWORD>(buffer->NumberOfEntries));
		for (unsigned int i = 0; i < number_of_entries; i++) {
			if (buffer->WorkingSetInfo[i].Shared) {
				ws_shareable++;
				if (buffer->WorkingSetInfo[i].ShareCount > 1)
					ws_shared++;
			}
			else {
				ws_private++;
			}
		}

		ws_usage->priv = ws_private * PAGESIZE_KB;
		ws_usage->shareable = ws_shareable * PAGESIZE_KB;
		ws_usage->shared = ws_shared * PAGESIZE_KB;
		free(buffer);
		return true;
	}
Пример #5
0
/**
 * @brief
 * Internal session memory usage decoding routine.
 * Accepts a job pointer.  Returns the sum of all memory
 * consumed for all tasks executed by the job, in kilo bytes.
 *
 * NOTE: To retrieve a handle to any process in the system,
 *       the calling process should have a privilege "SeDebugPrivilege".
 *       A Win32 API OpenProcess() can be used in a calling process
 *       to obtain any desired process handle in the system.
 *
 *       In PBS, ena_privilege() function can be used to enable
 *       SeDebugPrivilege for calling process. For pbs_mom process,
 *       ena_privilege() has been used in it's main_thread() function.
 *
 * @param[in]	pjob - pointer to job
 *
 * @return      u_Long
 * @retval      0 - failure
 * @retval      memory usage of all the processes of a job - failure
 */
static u_Long
mem_sum(job *pjob)
{
	u_Long			mem = 0;
	int			nps = 0;
	DWORD			i;
	HANDLE			hProcess;
	DWORD			pidlistsize;
	DWORD			nwspages;
	SYSTEM_INFO		si;
	PJOBOBJECT_BASIC_PROCESS_ID_LIST	pProcessList;
	JOBOBJECT_BASIC_ACCOUNTING_INFORMATION	ji;
	pbs_task                *ptask = NULL;
	BOOL                    is_process_in_job = FALSE;

	/* Get the system info */
	GetSystemInfo(&si);

	/* Get the number of processes embedded in the job */
	if (pjob->ji_hJob != NULL &&
		QueryInformationJobObject(pjob->ji_hJob,
		JobObjectBasicAccountingInformation,
		&ji, sizeof(ji), NULL)) {
		nps = ji.TotalProcesses;
	}

	if (nps == 0) {
		pjob->ji_flags |= MOM_NO_PROC;
		return 0;
	}


	/* Compute the size of pid list */
	pidlistsize = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) +
		(nps-1) * sizeof(DWORD);

	pProcessList = (PJOBOBJECT_BASIC_PROCESS_ID_LIST) malloc(pidlistsize);
	if (pProcessList == NULL) {
		log_err(-1, "mem_sum:", "memory allocation failed");
		return (0);
	}

	pProcessList->NumberOfAssignedProcesses = nps;
	pProcessList->NumberOfProcessIdsInList = 0;

	/* Get the pid list */
	if (pjob->ji_hJob != NULL)
		QueryInformationJobObject(pjob->ji_hJob,
			JobObjectBasicProcessIdList,
			pProcessList, pidlistsize, NULL);

	/*
	 * Traverse through each process and find the
	 * memory used by that process during its execution.
	 */
	for (i = 0; i < (pProcessList->NumberOfProcessIdsInList); i++) {
		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
			PROCESS_VM_READ,
			FALSE, pProcessList->ProcessIdList[i]);
		if (hProcess != NULL) {
			(void)QueryWorkingSet(hProcess, &nwspages, sizeof(nwspages));
			mem += nwspages * (si.dwPageSize >> 10);
			CloseHandle(hProcess);

		}
	}