Apa itu byte pribadi, byte virtual, set kerja?

491

Saya mencoba menggunakan utilitas perfmon windows untuk men-debug kebocoran memori dalam suatu proses.

Beginilah cara perfmon menjelaskan persyaratan:

Working Set adalah ukuran saat ini, dalam byte, dari Working Set dari proses ini. Set Kerja adalah set halaman memori yang baru-baru ini disentuh oleh utas dalam proses. Jika memori bebas di komputer berada di atas ambang batas, halaman dibiarkan dalam Perangkat Kerja dari suatu proses bahkan jika mereka tidak digunakan. Ketika memori bebas jatuh di bawah ambang batas, halaman dipangkas dari Perangkat Kerja. Jika mereka diperlukan, mereka kemudian akan kesalahan-lunak kembali ke Perangkat Kerja sebelum meninggalkan memori utama.

Virtual Bytes adalah ukuran saat ini, dalam byte, dari ruang alamat virtual yang digunakan oleh proses. Penggunaan ruang alamat virtual tidak selalu menyiratkan penggunaan yang sesuai dari disk atau halaman memori utama. Ruang virtual terbatas, dan prosesnya dapat membatasi kemampuannya untuk memuat perpustakaan.

Private Bytes adalah ukuran saat ini, dalam byte, dari memori yang telah dialokasikan proses ini yang tidak dapat dibagi dengan proses lain.

Ini adalah pertanyaan yang saya miliki:

Apakah Private Bytes yang harus saya ukur untuk memastikan apakah prosesnya mengalami kebocoran karena tidak melibatkan pustaka bersama dan kebocoran, jika terjadi, akan berasal dari proses itu sendiri?

Berapa total memori yang dikonsumsi oleh proses? Apakah ini Virtual Bytes atau jumlah dari Virtual Bytes dan Working Set?

Apakah ada hubungan antara Private Bytes, Working Set dan Virtual Bytes?

Apakah ada alat lain yang memberikan ide yang lebih baik tentang penggunaan memori?

pankajt
sumber
3
Alat yang lebih baik adalah valgrind / helgrind, tetapi tidak di bawah Windows sayangnya :(
Kornel Kisielewicz
Apakah ini byte pribadi yang harus saya ukur untuk memastikan apakah prosesnya mengalami kebocoran. Jika byte pribadi dari suatu proses tidak bertambah maka Anda tidak memiliki kebocoran memori. Jika mereka tumbuh mungkin karena kebocoran memori dan mungkin karena fragmentasi memori. Saya pikir sulit untuk mengatakan melihat pertumbuhan byte pribadi apa artinya sebenarnya.
@SergeiKurenkov Satu hal yang dapat kita katakan adalah bahwa PERNAH disebabkan oleh "fragmentasi memori".
Jamie Hanrahan

Jawaban:

517

Jawaban singkat untuk pertanyaan ini adalah bahwa tidak satu pun dari nilai-nilai ini merupakan indikator yang dapat diandalkan berapa banyak memori yang dapat dieksekusi sebenarnya, dan tidak ada yang benar-benar sesuai untuk men-debug kebocoran memori.

Private Bytes merujuk pada jumlah memori yang diminta oleh proses yang dapat dieksekusi - belum tentu jumlah yang sebenarnya digunakan . Mereka "pribadi" karena mereka (biasanya) mengecualikan file yang dipetakan memori (yaitu DLL bersama). Tapi - inilah intinya - mereka tidak selalu mengecualikan memori yang dialokasikan oleh file-file itu . Tidak ada cara untuk mengetahui apakah perubahan byte pribadi disebabkan oleh executable itu sendiri, atau karena pustaka tertaut. Bytes pribadi juga bukan hanya memori fisik; mereka dapat dipetakan ke disk atau dalam daftar halaman siaga (yaitu tidak lagi digunakan, tetapi belum juga halaman).

Working Set mengacu pada total memori fisik (RAM) yang digunakan oleh proses. Namun, tidak seperti byte pribadi, ini juga termasuk file yang dipetakan memori dan berbagai sumber daya lainnya, jadi ini bahkan pengukuran yang kurang akurat daripada byte pribadi. Ini adalah nilai yang sama dengan yang dilaporkan dalam "Mem Penggunaan" oleh Task Manager dan telah menjadi sumber kebingungan yang tak berkesudahan dalam beberapa tahun terakhir. Memori dalam Perangkat Kerja adalah "fisik" dalam arti bahwa itu dapat diatasi tanpa kesalahan halaman; namun, daftar halaman siaga juga masih secara fisik berada dalam memori tetapi tidak dilaporkan dalam Perangkat Kerja, dan inilah sebabnya Anda mungkin melihat "Mem Penggunaan" tiba-tiba turun ketika Anda meminimalkan suatu aplikasi.

Virtual Bytes adalah total ruang alamat virtual yang digunakan oleh seluruh proses. Ini seperti set yang berfungsi, dalam arti bahwa itu termasuk file yang dipetakan memori (DLL bersama), tetapi juga termasuk data dalam daftar siaga dan data yang telah paged keluar dan duduk di file halaman pada disk di suatu tempat. Total byte virtual yang digunakan oleh setiap proses pada suatu sistem di bawah beban berat akan menambah hingga secara signifikan lebih banyak memori daripada mesin sebenarnya.

Jadi hubungannya adalah:

  • Bytes Pribadi adalah apa yang sebenarnya dialokasikan aplikasi Anda, tetapi sertakan penggunaan pagefile;
  • Working Set adalah Private Bytes yang non-paged plus file yang dipetakan dengan memori;
  • Bytes Virtual adalah Set Kerja plus byte Pribadi dan daftar siaga.

Ada masalah lain di sini; sama seperti pustaka bersama dapat mengalokasikan memori di dalam modul aplikasi Anda, yang mengarah ke potensi kesalahan positif yang dilaporkan dalam Private Bytes aplikasi Anda , aplikasi Anda mungkin juga akhirnya mengalokasikan memori di dalam modul bersama , yang mengarah ke negatif palsu . Itu berarti sebenarnya mungkin bagi aplikasi Anda untuk memiliki kebocoran memori yang tidak pernah memanifestasikan dirinya dalam Private Bytes sama sekali. Tidak mungkin, tetapi mungkin.

Private Bytes adalah perkiraan yang masuk akal dari jumlah memori yang dapat dieksekusi yang Anda gunakan dan dapat digunakan untuk membantu mempersempit daftar kandidat potensial untuk kebocoran memori; jika Anda melihat jumlahnya terus bertambah dan terus-menerus dan tanpa akhir, Anda ingin memeriksa prosesnya apakah ada kebocoran. Namun, ini tidak dapat membuktikan bahwa ada kebocoran atau tidak.

Salah satu alat paling efektif untuk mendeteksi / memperbaiki kebocoran memori di Windows sebenarnya adalah Visual Studio (tautan menuju halaman tentang menggunakan VS untuk kebocoran memori, bukan halaman produk). Purifikasi Rasional adalah kemungkinan lain. Microsoft juga memiliki dokumen praktik terbaik yang lebih umum tentang hal ini. Ada lebih banyak alat yang tercantum dalam pertanyaan sebelumnya ini .

Saya harap ini membersihkan beberapa hal! Melacak kebocoran memori adalah salah satu hal paling sulit dilakukan dalam debugging. Semoga berhasil.

Aaronaught
sumber
26
Saya khawatir jawaban Anda kurang tepat. Private Bytes merujuk pada jumlah memori (RAM) yang diminta oleh proses yang dapat dieksekusi - tidak hanya memori fisik. Dengan demikian Anda pasti dapat memeriksa sebagian besar kasus kebocoran memori dengan memantau byte pribadi. Coba :: VisualAlloc untuk melakukan sebagian besar memori (katakanlah 1.5G). Anda harus dapat melihat bahwa byte pribadi Anda jauh lebih besar daripada set kerja. Yang membuktikan bahwa "Perangkat Kerja Anda adalah Private Bytes plus file yang dipetakan dengan Memori" salah.
Jay Zhu
4
Sebenarnya, saya percaya pemahaman menulis adalah "Set Kerja adalah di-memori Private Bytes plus file yang dipetakan Memori". Dan Private Bytes BISA ditukar - Anda dapat melihat byte pribadi lebih besar dari memori fisik yang Anda miliki di mesin.
Jay Zhu
2
@Aaronaught: Pernyataan pertama Anda tentang indikator yang andal dan tepat untuk debugging membingungkan. Bytes pribadi adalah indikator andal kebocoran ruang memori aplikasi. Ini bisa menjadi DLL dependen dan tidak langsung tetapi merupakan kebocoran di ruang memori aplikasi. Bisakah Anda menjelaskan mengapa itu tidak dapat digunakan untuk debugging? dump memori penuh dari proses aplikasi harus memberi tahu kami apa yang memakan memori ini. Saya tidak yakin saya mengerti mengapa itu tidak dapat digunakan untuk debugging. Bisakah Anda menjelaskan?
G33kKahuna
@ G33kKahuna: Tidak jelas bagi saya bagaimana memori dump akan memberi tahu Anda apa yang memakan memori dalam arti yang berarti - kecuali dengan "apa" maksud Anda "modul apa", tetapi semua yang Anda miliki hanyalah foto, Anda masih tidak dapat melihat modul mana yang sebenarnya membocorkan memori dari waktu ke waktu kecuali jika Anda mengambil beberapa dump dari waktu ke waktu dan dalam kondisi yang dikontrol dengan ketat. Sulit membayangkan strategi debugging yang lebih tidak efisien dan tidak dapat diandalkan. Profiler ada di mana-mana saat ini; gunakan satu.
Aaronaught
1
Jalankan penuh! Keberatan, ini harus menunjukkan benda yang disematkan di tumpukan langsung. Anda dapat mengonfirmasi dengan memeriksa eeheap -gc. Ini akan menunjukkan kepada Anda di mana volume macet. Biasanya, jika tidak ada petunjuk yang tersedia dengan semua perintah di atas, byte pribadi Anda dikonsumsi oleh objek yang tidak terkumpul di GC. Sekarang beralihlah ke gchandles atau gcleaks. Perintah-perintah ini harus memberi tahu Anda apa jenis / objek alamat tidak dapat dipetakan. Pointer masih ada tetapi objek hilang. Ini adalah masalah kategorikal untuk penangan acara yang belum dirilis.
G33kKahuna
10

Anda tidak boleh mencoba menggunakan perfmon, task manager atau alat apa pun seperti itu untuk menentukan kebocoran memori. Mereka baik untuk mengidentifikasi tren, tetapi tidak banyak yang lain. Angka-angka yang mereka laporkan secara absolut terlalu kabur dan digabungkan untuk berguna untuk tugas tertentu seperti deteksi kebocoran memori.

Balasan sebelumnya untuk pertanyaan ini telah memberikan penjelasan yang bagus tentang berbagai jenisnya.

Anda bertanya tentang rekomendasi alat: Saya merekomendasikan Memory Validator. Mampu memonitor aplikasi yang membuat milyaran alokasi memori.

http://www.softwareverify.com/cpp/memory/index.html

Penafian: Saya merancang Memory Validator.

Stephen Kellett
sumber
1
Saya bahkan tidak bisa menjalankan file kelas sederhana (di Jawa)? Apa yang menyebabkannya?
jn1kk
Saya menduga bahwa Stephen dan Iblis entah bagaimana terkait atau bahkan dikloning ...: D;)
Robert Koritnik
@StephenKellett, Apakah ada versi uji coba?
Pacerier
@Pacerier jika Anda mengikuti tautan ada percobaan untuk versi x86 dan x64 tepat di atas opsi beli di sebelah kiri halaman.
Bradley A. Tetreault
10

Definisi penghitung perfmon telah rusak sejak awal dan karena alasan tertentu tampaknya terlalu sulit untuk diperbaiki.

Tinjauan umum manajemen memori Windows tersedia dalam video " Misteri Manajemen Memori Terungkap " di MSDN: Ini mencakup lebih banyak topik daripada yang dibutuhkan untuk melacak kebocoran memori (misalnya manajemen pengaturan kerja) tetapi memberikan detail yang cukup dalam topik yang relevan.


Untuk memberi Anda sedikit masalah dengan deskripsi penghitung perfmon, berikut adalah kisah orang dalam tentang byte pribadi dari " Penghitung Kinerja Private Bytes - Waspadalah! " Di MSDN:

T: Kapan Private Byte bukan Private Byte?

A: Ketika itu bukan penduduk.

Penghitung Private Bytes melaporkan biaya komit dari proses. Dengan kata lain, jumlah ruang yang telah dialokasikan dalam file swap untuk menampung konten dari memori pribadi jika terjadi pertukaran. Catatan: Saya menghindari kata "dilindungi undang-undang" karena kemungkinan kebingungan dengan memori virtual dalam status cadangan yang tidak dilakukan.


Dari " Perencanaan Kinerja " di MSDN:

3.3 Bytes Pribadi

3.3.1 Deskripsi

Memori pribadi, didefinisikan sebagai memori yang dialokasikan untuk suatu proses yang tidak dapat dibagi oleh proses lain. Memori ini lebih mahal daripada memori bersama ketika beberapa proses tersebut dijalankan pada mesin. Memori pribadi dalam dll yang tidak terkelola (tradisional) biasanya terdiri dari statika C ++ dan memiliki urutan 5% dari total set kerja dll.

Menandai
sumber
1
memilih karena contoh-contoh bagus tentang bagaimana itu rusak!
Bruno Brant
Kutipan pertama salah. Mengalokasikan "Private byte" tidak memerlukan apa pun yang "dialokasikan dalam file swap" (yang sebenarnya disebut pagefile). Anda bahkan tidak perlu memiliki file halaman untuk "byte pribadi" untuk dialokasikan. Bahkan, mengalokasikan byte pribadi tidak segera menggunakan ruang apa pun di mana pun , dan mungkin tidak pernah menggunakan sebanyak yang dialokasikan.
Jamie Hanrahan
Kutipan kedua tidak jauh lebih baik. Bytes pribadi yang digunakan dalam kode DLL tidak selalu sebagian besar dialokasikan secara statis di dalam DLL. Kode DLL benar-benar gratis untuk memanggil VirtualAlloc, HeapAlloc (malloc dan baru di CRTL), dll. Ia juga mencoba menggambarkan ukuran memori pribadi sebagai persentase dari ukuran set yang berfungsi, yang tidak masuk akal. Yang pertama adalah ukuran virtual (dan akan sama untuk setiap penggunaan kode dengan input yang sama) sedangkan yang kedua adalah fisik (yang dapat sangat berbeda dari satu menjalankan ke yang berikutnya, tergantung pada berapa banyak memori yang kaya atau - mesin kelaparan adalah).
Jamie Hanrahan
5

Ada diskusi yang menarik di sini: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Pemahaman saya tentang utas ini adalah membebaskan alokasi kecil adalah tidak tercermin dalam Private Bytes atau Working Set.

Singkat cerita:

jika saya menelepon

p=malloc(1000);
free(p);

maka Private Bytes hanya mencerminkan alokasi, bukan alokasi.

jika saya menelepon

p=malloc(>512k);
free(p);

maka Private Bytes mencerminkan alokasi dan deallokasi dengan benar.

mcanti
sumber
7
Ini dijelaskan oleh fakta bahwa fungsi memori library C standar menggunakan custom atau Win32 Heap yang merupakan mekanisme manajemen memori di atas manajemen memori level proses level rendah.
Kyberias
@ Kirberias, Jadi bagaimana kita bisa berada di bawah itu?
Pacerier
sementara (1) gratis (malloc (1000)); // Apakah ini akan menyebabkan Bytes Pribadi meningkat selamanya?
franckspike
2
@franckspike: tidak, itu akan meningkat ke titik tertentu (umumnya sekitar 4 kB, tetapi ini dapat bervariasi) dan kemudian berhenti, karena CRT akan menggunakan kembali memori yang sebelumnya telah dibebaskan alih-alih meminta halaman baru dari OS.
Miral
@Pacerier: Anda dapat menghubungi VirtualAlloc dan VirtualFree.
Jamie Hanrahan