Kiedyś miałem za zadanie określić następujące parametry wydajności z działającej aplikacji:
- Całkowita dostępna pamięć wirtualna
- Aktualnie używana pamięć wirtualna
- Pamięć wirtualna aktualnie używana przez mój proces
- Całkowita dostępna pamięć RAM
- Aktualnie używana pamięć RAM
- Pamięć RAM aktualnie używana przez mój proces
- % Aktualnie używanego procesora
- % Procesora aktualnie używanego przez mój proces
Kod musiał działać w systemie Windows i Linux. Mimo że wydaje się to być standardowym zadaniem, znalezienie niezbędnych informacji w instrukcjach (interfejs API WIN32, dokumenty GNU) oraz w Internecie zajęło mi kilka dni, ponieważ jest tak wiele niekompletnych / niepoprawnych / nieaktualnych informacji na ten temat. znalazłem tam.
Aby uratować innych przed podobnymi problemami, pomyślałem, że dobrym pomysłem będzie zebranie w jednym miejscu wszystkich rozproszonych informacji oraz tego, co znalazłem metodą prób i błędów.
Odpowiedzi:
Windows
Niektóre z powyższych wartości są łatwo dostępne z odpowiedniego interfejsu API WIN32, po prostu podaję je tutaj dla kompletności. Inne należy jednak uzyskać z biblioteki Performance Data Helper (PDH), która jest nieco „nieintuicyjna” i wymaga wielu bolesnych prób i błędów, aby zabrać się do pracy. (Przynajmniej zajęło mi to trochę czasu, być może byłem tylko trochę głupi ...)
Uwaga: dla jasności wszystkie sprawdzanie błędów zostało pominięte w poniższym kodzie. Sprawdź kody powrotne ...!
Całkowita pamięć wirtualna:
Uwaga: nazwa „TotalPageFile” jest tutaj nieco myląca. W rzeczywistości parametr ten podaje „Rozmiar pamięci wirtualnej”, który jest rozmiarem pliku wymiany plus zainstalowanej pamięci RAM.
Aktualnie używana pamięć wirtualna:
Taki sam kod jak w „Total Virtual Memory”, a następnie
Pamięć wirtualna aktualnie używana przez bieżący proces:
Całkowita pamięć fizyczna (RAM):
Taki sam kod jak w „Total Virtual Memory”, a następnie
Aktualnie używana pamięć fizyczna:
Pamięć fizyczna aktualnie używana przez bieżący proces:
Taki sam kod jak w „Pamięci wirtualnej obecnie używanej przez bieżący proces”, a następnie
Aktualnie używany procesor:
Procesor aktualnie używany przez bieżący proces:
Linux
W systemie Linux wybór, który na pierwszy rzut oka wydawał się oczywisty, polegał na użyciu interfejsów API POSIX, takich jak
getrusage()
itp. Spędziłem trochę czasu starając się, aby to zadziałało, ale nigdy nie uzyskałem znaczących wartości. Kiedy w końcu sprawdziłem same źródła jądra, dowiedziałem się, że najwyraźniej te interfejsy API nie są jeszcze w pełni zaimplementowane w jądrze Linuksa 2.6 !?Ostatecznie wszystkie wartości uzyskałem przez połączenie odczytu pseudo-systemu plików
/proc
i wywołań jądra.Całkowita pamięć wirtualna:
Aktualnie używana pamięć wirtualna:
Taki sam kod jak w „Total Virtual Memory”, a następnie
Pamięć wirtualna aktualnie używana przez bieżący proces:
Całkowita pamięć fizyczna (RAM):
Taki sam kod jak w „Total Virtual Memory”, a następnie
Aktualnie używana pamięć fizyczna:
Taki sam kod jak w „Total Virtual Memory”, a następnie
Pamięć fizyczna aktualnie używana przez bieżący proces:
Zmień getValue () w „Pamięci wirtualnej aktualnie używanej przez bieżący proces” w następujący sposób:
Aktualnie używany procesor:
Procesor aktualnie używany przez bieżący proces:
DO ZROBIENIA: Inne platformy
Zakładam, że część kodu Linuksa działa również dla Uniksa, z wyjątkiem części, które czytają pseudo-system plików / proc. Być może w Unixie te części można zastąpić
getrusage()
podobnymi funkcjami? Jeśli ktoś z wiedzą na temat Uniksa mógłby edytować tę odpowiedź i wypełnić szczegóły ?!źródło
PROCESS_MEMORY_COUNTERS
, w jaki sposób pobierasz „Pamięć wirtualną aktualnie używaną przez bieżący proces”?PrivateUsage
nie jest członkiemPROCESS_MEMORY_COUNTERS
jest błąd kompilatora, który otrzymuję!"quotes like these"
do dołączania nagłówków systemowych?GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
jąGetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
Mac OS X
Miałem też nadzieję znaleźć podobne informacje dla Mac OS X. Ponieważ go tu nie było, wyszedłem i sam go wykopałem. Oto niektóre z rzeczy, które znalazłem. Jeśli ktoś ma jakieś inne sugestie, chciałbym je usłyszeć.
Całkowita pamięć wirtualna
Ten jest trudny w systemie Mac OS X, ponieważ nie korzysta ze wstępnie ustawionej partycji wymiany ani pliku takiego jak Linux. Oto wpis z dokumentacji Apple:
Jeśli więc chcesz wiedzieć, ile pamięci wirtualnej jest nadal dostępne, musisz uzyskać rozmiar partycji głównej. Możesz to zrobić w następujący sposób:
Łącznie aktualnie używane wirtualne
Wywołanie systcl za pomocą klawisza „vm.swapusage” dostarcza interesujących informacji o użyciu wymiany:
Nie oznacza to, że całkowite użycie wymiany może się zmienić, jeśli potrzeba więcej wymiany, jak wyjaśniono w powyższej sekcji. Tak więc suma jest w rzeczywistości bieżącą sumą wymiany. W języku C ++ dane można przeszukiwać w następujący sposób:
Zauważ, że „xsw_usage”, zadeklarowany w sysctl.h, wydaje się nieudokumentowany i podejrzewam, że istnieje bardziej przenośny sposób dostępu do tych wartości.
Pamięć wirtualna aktualnie używana przez mój proces
Za pomocą tej
task_info
funkcji można uzyskać statystyki dotyczące bieżącego procesu . Obejmuje to bieżący rozmiar rezydenta procesu i bieżący rozmiar wirtualny.Całkowita dostępna pamięć RAM
Ilość fizycznej pamięci RAM dostępnej w twoim systemie jest dostępna za pomocą
sysctl
funkcji systemowej w następujący sposób:Aktualnie używana pamięć RAM
Ogólne statystyki pamięci można uzyskać z
host_statistics
funkcji systemu.Należy tutaj zauważyć, że w systemie Mac OS X istnieje pięć rodzajów stron pamięci. Są to:
Warto zauważyć, że tylko dlatego, że Mac OS X może czasami wykazywać bardzo mało rzeczywistej wolnej pamięci, może nie być dobrym wskaźnikiem tego, ile jest gotowe do użycia w krótkim czasie.
Pamięć RAM aktualnie używana przez mój proces
Zobacz „Pamięć wirtualna aktualnie używana przez mój proces” powyżej. Obowiązuje ten sam kod.
źródło
Linux
W systemie Linux informacje te są dostępne w systemie plików / proc. Nie jestem wielkim fanem używanego formatu pliku tekstowego, ponieważ każda dystrybucja Linuksa wydaje się dostosowywać co najmniej jeden ważny plik. Szybkie spojrzenie na źródło „ps” ujawnia bałagan.
Ale tutaj znajdziesz informacje, których szukasz:
/ proc / meminfo zawiera większość informacji ogólnosystemowego szukacie. Tutaj wygląda jak w moim systemie; Myślę, że interesują Cię MemTotal , MemFree , SwapTotal i SwapFree :
Aby wykorzystać procesor, musisz trochę popracować. Linux udostępnia ogólne wykorzystanie procesora od momentu uruchomienia systemu; prawdopodobnie nie jest to tym, czym jesteś zainteresowany. Jeśli chcesz wiedzieć, jakie było wykorzystanie procesora przez ostatnią sekundę lub 10 sekund, musisz zapytać o informacje i sam je obliczyć.
Informacje są dostępne w / proc / stat , który jest dość dobrze udokumentowany na stronie http://www.linuxhowtos.org/System/procstat.htm ; oto jak to wygląda na moim 4-rdzeniowym pudełku:
Najpierw musisz określić, ile procesorów (lub procesorów lub rdzeni przetwarzających) jest dostępnych w systemie. Aby to zrobić, policz liczbę wpisów „cpuN”, gdzie N zaczyna się od 0 i zwiększa. Nie licz linii „cpu”, która jest kombinacją linii cpuN. W moim przykładzie możesz zobaczyć cpu0 do cpu3, w sumie 4 procesory. Od teraz możesz ignorować cpu0..cpu3 i skupiać się tylko na linii „cpu”.
Następnie musisz wiedzieć, że czwarta liczba w tych wierszach jest miarą czasu bezczynności, a zatem czwarta liczba w linii „procesora” to całkowity czas bezczynności dla wszystkich procesorów od czasu rozruchu. Czas ten mierzony jest w „jiffies” Linuksa, które wynoszą 1/100 sekundy każda.
Ale nie obchodzi cię całkowity czas bezczynności; zależy Ci na czasie bezczynności w danym okresie, np. w ostatniej sekundzie. Oblicz to, musisz przeczytać ten plik dwa razy, w odstępie 1 sekundy. Następnie możesz wykonać różnicę czwartej wartości linii. Na przykład, jeśli weźmiesz próbkę i otrzymasz:
Następnie sekundę później otrzymujesz tę próbkę:
Odejmij dwie liczby, a otrzymasz różnicę 396, co oznacza, że twój procesor był bezczynny przez 3,96 sekundy z ostatniego 1,00 sekundy. Sztuczka polega oczywiście na tym, że musisz podzielić liczbę procesorów. 3,96 / 4 = 0,99, a jest twój bezczynny procent; 99% bezczynności i 1% zajęty.
W moim kodzie mam bufor pierścieniowy zawierający 360 wpisów i czytam ten plik co sekundę. To pozwala mi szybko obliczyć wykorzystanie procesora przez 1 sekundę, 10 sekund itp., Aż do 1 godziny.
Aby uzyskać informacje specyficzne dla procesu, musisz poszukać w / proc / pid ; jeśli nie obchodzi cię twój pid, możesz zajrzeć do / proc / self.
Procesor używany przez proces jest dostępny w / proc / self / stat . Jest to dziwnie wyglądający plik składający się z jednej linii; na przykład:
Ważnymi danymi są tutaj 13 i 14 żeton (tutaj 0 i 770). 13. token to liczba jiffies, które proces wykonał w trybie użytkownika, a 14. to liczba jiffies, które proces wykonał w trybie jądra. Dodaj oba razem, a uzyskasz całkowite wykorzystanie procesora.
Ponownie będziesz musiał okresowo próbkować ten plik i obliczać różnicę, aby określić zużycie procesora przez proces w czasie.
Edytować: pamiętaj, że obliczając wykorzystanie procesora przez proces, należy wziąć pod uwagę 1) liczbę wątków w procesie i 2) liczbę procesorów w systemie. Na przykład, jeśli proces jednowątkowy zużywa tylko 25% procesora, może to być dobre lub złe. Dobry w systemie jednoprocesorowym, ale zły w systemie 4-procesorowym; oznacza to, że proces działa nieprzerwanie i wykorzystuje 100% dostępnych cykli procesora.
Aby uzyskać informacje o pamięci specyficzne dla procesu, należy spojrzeć na / proc / self / status, który wygląda następująco:
Wpisy zaczynające się od „Vm” to interesujące:
Jedynym elementem, którego nie jestem pewien, jest Swapspace, który jest obecnie używany przez mój proces . Nie wiem czy to jest dostępne.
źródło
w systemie Windows można uzyskać użycie procesora przez poniższy kod:
źródło
usage =
jest najbardziej kreatywną rzeczą, jaką widziałem od jakiegoś czasu, w ogóle nieczytelną, ale kreatywnąULONGLONG
Dla VS zamiastULARGE_INTEGER
. 2) Dzwonisz, nadmiernie komplikujesz rzeczyCopyMemory()
, po prostu zrób toULONGLONG ul_sys_idle = *(ULONGLONG*)&ft_sys_idle;
zamiast tego. Zostanie przetłumaczony na pojedynczą instrukcję CPUmov
(lublea
).Linux
Przenośnym sposobem odczytu pamięci i numerów ładowania jest
sysinfo
połączenieStosowanie
OPIS
źródło
QNX
Ponieważ jest to jak „wikipage kodu”, chcę dodać kod z bazy wiedzy QNX (uwaga: to nie moja praca, ale sprawdziłem ją i działa dobrze w moim systemie):
Jak uzyskać użycie procesora w%: http://www.qnx.com/support/knowledgebase.html?id=50130000000P9b5
Jak uzyskać bezpłatną (!) Pamięć: http://www.qnx.com/support/knowledgebase.html?id=50130000000mlbbx
źródło
Mac OS X - procesor
Ogólne użycie procesora:
Od Pobierz informacje o systemie na MacOS X? :
źródło
W systemie Linux można również użyć / proc / self / statm, aby uzyskać pojedynczy wiersz liczb zawierający kluczowe informacje o pamięci procesu, co jest szybsze niż przetworzenie długiej listy zgłaszanych informacji uzyskanych z proc / self / status
Zobacz http://man7.org/linux/man-pages/man5/proc.5.html
źródło
Użyłem tego kodu w moim projekcie C ++ i działało dobrze:
źródło