Seperti yang orang lain tunjukkan dengan benar, sulit untuk menangani memori aktual yang digunakan oleh suatu proses, apa dengan daerah yang dibagikan, dan file mmap'ed dan yang lainnya.
Jika Anda seorang eksperimen, Anda dapat menjalankan valgrind dan massif . Ini mungkin menjadi agak berat bagi pengguna biasa tetapi Anda akan mendapatkan gagasan tentang perilaku memori aplikasi dari waktu ke waktu. Jika sebuah aplikasi malloc () adalah persis apa yang dibutuhkannya maka ini akan memberi Anda representasi yang baik dari penggunaan memori dinamis nyata dari suatu proses. Tapi percobaan ini bisa "diracuni".
Untuk memperumit masalah, Linux memungkinkan Anda untuk membuat terlalu banyak ingatan. Saat Anda malloc () memori, Anda menyatakan niat Anda untuk mengkonsumsi memori. Tetapi alokasi tidak benar-benar terjadi sampai Anda menulis byte ke halaman baru dari "RAM" yang dialokasikan. Anda dapat membuktikan ini pada diri sendiri dengan menulis dan menjalankan program C kecil seperti:
// test.c
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
void *p;
sleep(5)
p = malloc(16ULL*1024*1024*1024);
printf("p = %p\n", p);
sleep(30);
return 0;
}
# Shell:
cc test.c -o test && ./test &
top -p $!
Jalankan ini pada mesin dengan kurang dari 16GB RAM dan, voila !, Anda baru saja mencetak 16GB memori! (tidak terlalu).
Perhatikan bahwa top
Anda melihat "VIRT" sebagai 16,004G tetapi% MEM adalah 0,0
Jalankan ini lagi dengan valgrind:
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
Dan massif mengatakan "jumlah semua allocs () = 16GB". Jadi itu tidak terlalu menarik.
TAPI, jika Anda menjalankannya pada proses yang waras :
# Shell:
rm test test.o
valgrind --tool=massif cc test.c -o test &
sleep 3
ms_print massif.out.$! | head -n 30
--------------------------------------------------------------------------------
Command: cc test.c -o test
Massif arguments: (none)
ms_print arguments: massif.out.23988
--------------------------------------------------------------------------------
KB
77.33^ :
| #:
| :@::@:#:
| :::::@@::@:#:
| @:: :::@@::@:#:
| ::::@:: :::@@::@:#:
| ::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| :@@@@@@@@@@@@@@@@@@@@:@::@:::@:::::@:: :::@@::@:#:
| :@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
0 +----------------------------------------------------------------------->Mi
0 1.140
Dan di sini kita melihat (sangat empiris dan dengan keyakinan sangat tinggi) bahwa kompiler mengalokasikan 77KB tumpukan.
Mengapa berusaha sangat keras untuk mendapatkan hanya tumpukan penggunaan? Karena semua objek dan bagian teks yang digunakan bersama oleh suatu proses (dalam contoh ini, kompiler) tidak terlalu menarik. Mereka overhead konstan untuk suatu proses. Bahkan, doa selanjutnya dari proses tersebut hampir datang secara "gratis".
Juga, bandingkan dan kontraskan yang berikut ini:
MMAP () file 1GB. VMSize Anda akan menjadi 1 + GB. Tapi Anda Resident Set Size hanya akan menjadi bagian dari file yang Anda paging (dengan mendereferensi pointer ke wilayah itu). Dan jika Anda "membaca" seluruh file kemudian, pada saat Anda sampai di akhir, kernel mungkin sudah membuka awal (ini mudah dilakukan karena kernel tahu persis bagaimana / di mana untuk mengganti halaman-halaman itu jika direferensi lagi ). Dalam kedua kasus tersebut, baik VMSize maupun RSS bukanlah indikator yang baik untuk "penggunaan" memori Anda. Anda belum benar-benar malloc () melakukan sesuatu.
Sebaliknya, Malloc () dan sentuh LOTS memori - hingga memori Anda ditukar ke disk. Jadi memori yang dialokasikan sekarang melebihi RSS Anda. Di sini, VMSize Anda mungkin mulai memberi tahu Anda sesuatu (proses Anda memiliki lebih banyak memori daripada yang sebenarnya tersimpan di RAM Anda). Tetapi masih sulit untuk membedakan antara VM yang berbagi halaman dan VM yang bertukar data.
Di sinilah valgrind / massif menjadi menarik. Ini menunjukkan kepada Anda apa yang telah Anda alokasikan dengan sengaja (terlepas dari keadaan halaman Anda).
htop
penulis untuk satu pertanyaan serupa yang saya miliki