Saya perlu mendapatkan penggunaan mem VIRT dan RES pada saat program saya dijalankan dan menampilkannya.
Apa yang saya coba sejauh ini:
getrusage ( http://linux.die.net/man/2/getrusage )
int who = RUSAGE_SELF;
struct rusage usage;
int ret;
ret=getrusage(who,&usage);
cout<<usage.ru_maxrss;
tapi saya selalu mendapatkan 0.
Jawaban:
Di Linux, saya tidak pernah menemukan solusi ioctl () . Untuk aplikasi kami, kami membuat kode rutin utilitas umum berdasarkan membaca file di / proc / pid . Ada beberapa file ini yang memberikan hasil yang berbeda. Inilah yang kami selesaikan (pertanyaannya diberi tag C ++, dan kami menangani I / O menggunakan konstruksi C ++, tetapi harus mudah beradaptasi dengan rutinitas C i / o jika Anda perlu):
#include <unistd.h> #include <ios> #include <iostream> #include <fstream> #include <string> ////////////////////////////////////////////////////////////////////////////// // // process_mem_usage(double &, double &) - takes two doubles by reference, // attempts to read the system-dependent data for a process' virtual memory // size and resident set size, and return the results in KB. // // On failure, returns 0.0, 0.0 void process_mem_usage(double& vm_usage, double& resident_set) { using std::ios_base; using std::ifstream; using std::string; vm_usage = 0.0; resident_set = 0.0; // 'file' stat seems to give the most reliable results // ifstream stat_stream("/proc/self/stat",ios_base::in); // dummy vars for leading entries in stat that we don't care about // string pid, comm, state, ppid, pgrp, session, tty_nr; string tpgid, flags, minflt, cminflt, majflt, cmajflt; string utime, stime, cutime, cstime, priority, nice; string O, itrealvalue, starttime; // the two fields we want // unsigned long vsize; long rss; stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >> nice >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest stat_stream.close(); long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages vm_usage = vsize / 1024.0; resident_set = rss * page_size_kb; } int main() { using std::cout; using std::endl; double vm, rss; process_mem_usage(vm, rss); cout << "VM: " << vm << "; RSS: " << rss << endl; }
sumber
why 1024.0?
- Ia memberitahu compiler untuk mengkonversi ke double FIRST dan kemudian melakukan pembagian untuk mendapatkan hasil double. Pilihan lainnya:vm_usage = vsize / 1024;
akan melakukan pembagian terlebih dahulu, (kehilangan presisi seperti yang diisyaratkan @DonWakefield) dan kemudian ubah menjadi dua kali lipat.David Robert Nadeau telah menempatkan fungsi C multi-platform mandiri yang baik untuk mendapatkan ukuran set residen proses (penggunaan memori fisik) di situsnya:
/* * Author: David Robert Nadeau * Site: http://NadeauSoftware.com/ * License: Creative Commons Attribution 3.0 Unported License * http://creativecommons.org/licenses/by/3.0/deed.en_US */ #if defined(_WIN32) #include <windows.h> #include <psapi.h> #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) #include <unistd.h> #include <sys/resource.h> #if defined(__APPLE__) && defined(__MACH__) #include <mach/mach.h> #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) #include <fcntl.h> #include <procfs.h> #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) #include <stdio.h> #endif #else #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS." #endif /** * Returns the peak (maximum so far) resident set size (physical * memory use) measured in bytes, or zero if the value cannot be * determined on this OS. */ size_t getPeakRSS( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.PeakWorkingSetSize; #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) /* AIX and Solaris ------------------------------------------ */ struct psinfo psinfo; int fd = -1; if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 ) return (size_t)0L; /* Can't open? */ if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) ) { close( fd ); return (size_t)0L; /* Can't read? */ } close( fd ); return (size_t)(psinfo.pr_rssize * 1024L); #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) /* BSD, Linux, and OSX -------------------------------------- */ struct rusage rusage; getrusage( RUSAGE_SELF, &rusage ); #if defined(__APPLE__) && defined(__MACH__) return (size_t)rusage.ru_maxrss; #else return (size_t)(rusage.ru_maxrss * 1024L); #endif #else /* Unknown OS ----------------------------------------------- */ return (size_t)0L; /* Unsupported. */ #endif } /** * Returns the current resident set size (physical memory use) measured * in bytes, or zero if the value cannot be determined on this OS. */ size_t getCurrentRSS( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.WorkingSetSize; #elif defined(__APPLE__) && defined(__MACH__) /* OSX ------------------------------------------------------ */ struct mach_task_basic_info info; mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount ) != KERN_SUCCESS ) return (size_t)0L; /* Can't access? */ return (size_t)info.resident_size; #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) /* Linux ---------------------------------------------------- */ long rss = 0L; FILE* fp = NULL; if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL ) return (size_t)0L; /* Can't open? */ if ( fscanf( fp, "%*s%ld", &rss ) != 1 ) { fclose( fp ); return (size_t)0L; /* Can't read? */ } fclose( fp ); return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE); #else /* AIX, BSD, Solaris, and Unknown OS ------------------------ */ return (size_t)0L; /* Unsupported. */ #endif }
Pemakaian
size_t currentSize = getCurrentRSS( ); size_t peakSize = getPeakRSS( );
Untuk pembahasan lebih lanjut, periksa situs web, ini juga menyediakan fungsi untuk mendapatkan ukuran memori fisik suatu sistem .
sumber
#pragma comment(lib, "psapi.lib")
ke#if defined(_WIN32)
ruang lingkup.Tua:
Baru: Tampaknya cara di atas tidak benar-benar berfungsi, karena kernel tidak mengisi sebagian besar nilai. Apa yang berhasil adalah mendapatkan informasi dari proc. Alih-alih menguraikannya sendiri, lebih mudah menggunakan libproc (bagian dari procps) sebagai berikut:
// getrusage.c #include <stdio.h> #include <proc/readproc.h> int main() { struct proc_t usage; look_up_our_self(&usage); printf("usage: %lu\n", usage.vsize); }
Kompilasi dengan "
gcc -o getrusage getrusage.c -lproc
"sumber
#include <proc/readproc.h>
solusi bekerja besar bagi saya di bawah Ubuntu. Saya harus menginstal paketlibproc-dev
.usage.vm_data
adalah perkiraan yang cukup dekat dengan apa yang saya butuhkan. Pilihan statistik memori Anda didokumentasikan di sini:/usr/include/proc/readproc.h
Yang saya coba semuanya tampaknya dalam byte, bukan halaman. Saya tidak berpikir proses saya menggunakan 46 juta halaman. Komentar bahwa solusi ini tidak berfungsi di Linux tampaknya salah kaprah.Di linux, jika Anda mampu membayar biaya waktu proses (untuk debugging), Anda dapat menggunakan valgrind dengan alat massif:
http://valgrind.org/docs/manual/ms-manual.html
Ini berat, tapi sangat berguna.
sumber
Cara yang lebih elegan untuk metode Don Wakefield:
#include <iostream> #include <fstream> using namespace std; int main(){ int tSize = 0, resident = 0, share = 0; ifstream buffer("/proc/self/statm"); buffer >> tSize >> resident >> share; buffer.close(); long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages double rss = resident * page_size_kb; cout << "RSS - " << rss << " kB\n"; double shared_mem = share * page_size_kb; cout << "Shared Memory - " << shared_mem << " kB\n"; cout << "Private Memory - " << rss - shared_mem << "kB\n"; return 0; }
sumber
Jawaban yang ada lebih baik untuk bagaimana mendapatkan nilai yang benar, tapi setidaknya saya bisa menjelaskan mengapa getrusage tidak bekerja untuk Anda.
pria 2 getrusage:
sumber
sebagai tambahan untuk cara
Anda, Anda dapat memanggil perintah ps sistem dan mendapatkan penggunaan memori dari outputnya.
atau baca info dari / proc / pid (lihat PIOCPSINFO struct)
sumber
Di sistem Anda ada file bernama
/proc/self/statm
. Sistem file proc adalah sistem file semu yang menyediakan antarmuka ke struktur data kernel. File ini berisi informasi yang Anda butuhkan dalam kolom dengan hanya bilangan bulat yang dipisahkan spasi.Kolom no .:
= total ukuran program (VmSize di / proc / [pid] / status)
= ukuran set penduduk (VmRSS di / proc / [pid] / status)
Untuk info lebih lanjut lihat LINK .
sumber
Saya menggunakan cara lain untuk melakukan itu dan kedengarannya realistis. Apa yang saya lakukan adalah saya mendapatkan PID dari proses tersebut dengan fungsi getpid () dan kemudian saya menggunakan file / proc / pid / stat. Saya yakin kolom ke-23 dari file stat adalah vmsize (lihat posting Don). Anda dapat membaca vmsize dari file dimanapun Anda butuhkan dalam kode. Jika Anda bertanya-tanya berapa banyak potongan kode yang dapat menggunakan memori, Anda dapat membaca file itu satu kali sebelum potongan itu dan sekali setelahnya dan Anda dapat menguranginya satu sama lain.
sumber
Berdasarkan solusi Don W., dengan variabel yang lebih sedikit.
void process_mem_usage(double& vm_usage, double& resident_set) { vm_usage = 0.0; resident_set = 0.0; // the two fields we want unsigned long vsize; long rss; { std::string ignore; std::ifstream ifs("/proc/self/stat", std::ios_base::in); ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> vsize >> rss; } long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages vm_usage = vsize / 1024.0; resident_set = rss * page_size_kb; }
sumber
Saya sedang mencari aplikasi Linux untuk mengukur memori maksimum yang digunakan. valgrind adalah alat yang luar biasa, tetapi memberi saya lebih banyak informasi daripada yang saya inginkan. waktu tampaknya menjadi alat terbaik yang dapat saya temukan. Mengukur penggunaan memori "highwater" (RSS dan virtual). Lihat jawaban ini .
sumber