Kecuali anda're pemrograman bagian dari sebuah OS atau sistem tertanam apakah ada alasan untuk melakukannya? Saya bisa membayangkan bahwa untuk beberapa kelas-kelas tertentu yang diciptakan dan dihancurkan sering overloading fungsi-fungsi manajemen memori atau memperkenalkan sebuah kolam renang benda yang dapat menurunkan biaya overhead, tetapi melakukan hal-hal ini secara global?
Tambahan I've hanya menemukan bug dalam aplikasi yang kelebihan beban fungsi hapus memori itu't selalu dibebaskan. Dan yang ada di memori aplikasi kritis. Juga, menonaktifkan overload ini menurun kinerja oleh ~0.5% saja.
Kita membebani global yang baru dan menghapus operator mana saya bekerja untuk banyak alasan:
Ide baru/menghapus akuntansi adalah benar-benar fleksibel dan kuat: anda dapat, misalnya, merekam seluruh callstack untuk thread aktif setiap kali alloc terjadi, dan statistik agregat tentang itu. Anda bisa mengirimkan tumpukan info melalui jaringan jika anda don't memiliki ruang untuk menyimpannya secara lokal untuk alasan apapun. Jenis info yang anda dapat berkumpul di sini hanya dibatasi oleh imajinasi anda (dan kinerja, tentu saja).
Kami menggunakan global overload karena itu's mudah untuk menggantung banyak umum debugging fungsi yang ada, serta melakukan sweeping perbaikan di seluruh app, berdasarkan statistik yang kami kumpulkan dari orang-orang yang sama overload.
Kita masih lakukan menggunakan custom penyalur untuk masing-masing jenis juga, dalam banyak kasus speedup atau kemampuan yang anda bisa mendapatkan dengan menyediakan kustom penyalur misalnya single point-of-penggunaan STL struktur data jauh melebihi umum speedup yang bisa anda dapatkan dari global overload.
Lihatlah beberapa penyalur dan debugging sistem yang di luar sana untuk C/C++ dan anda'll cepat datang dengan ini dan ide-ide lain:
(Satu tua tapi buku mani adalah Tulisan Solid Kode, yang membahas banyak alasan anda mungkin ingin untuk memberikan kustom penyalur di C, yang sebagian besar masih sangat relevan.)
Jelas jika anda dapat menggunakan salah satu dari ini baik-baik saja alat-alat yang anda akan ingin untuk melakukannya daripada bergulir anda sendiri.
Ada situasi di mana hal ini lebih cepat, lebih mudah, lebih sedikit dari bisnis/hukum kerumitan, tidak ada's tersedia untuk platform anda belum, atau hanya lebih instruktif: menggali dan menulis sebuah global yang berlebihan.
Alasan yang paling umum untuk overload baru dan menghapus yang cukup untuk memeriksa kebocoran memori, dan penggunaan memori statistik. Perhatikan bahwa "kebocoran memori" biasanya umum untuk kesalahan memori. Anda dapat memeriksa hal-hal seperti double menghapus dan buffer overruns.
Penggunaan setelah itu biasanya memori-alokasi skema, seperti pengumpulan sampah, dan pooling.
Semua kasus lain adalah hanya hal-hal tertentu, yang disebutkan dalam jawaban lainnya (logging ke disk, kernel menggunakan).
Selain kegunaan yang penting disebutkan di sini, seperti memori tagging, it's juga satu-satunya cara untuk memaksa semua alokasi dalam aplikasi anda untuk pergi melalui fixed-blok alokasi, yang memiliki implikasi yang sangat besar bagi kinerja dan fragmentasi.
Misalnya, anda mungkin memiliki serangkaian memori kolam dengan tetap ukuran blok. Utama global baru
memungkinkan anda langsung semua 61-byte alokasi untuk, katakanlah, kolam dengan 64-byte blok, semua 768-1024 byte allocs ke 1024b-blok renang, semua orang yang di atas itu untuk 2048 byte blok renang, dan apa pun yang lebih besar dari 8kb untuk umum compang-camping tumpukan.
Karena blok tetap penyalur jauh lebih cepat dan kurang rentan terhadap fragmentasi dari mengalokasikan willy-nilly dari tumpukan, ini memungkinkan anda memaksa bahkan jelek 3d partai kode untuk mengalokasikan dari kolam anda dan tidak semua kotoran dari ruang alamat.
Hal ini sering dilakukan di sistem yang waktu dan ruang kritis, seperti games. 280Z28, Meeh, dan dan Olson telah dijelaskan mengapa.
UnrealEngine3 overload global yang baru dan menghapus sebagai bagian dari inti manajemen memori sistem. Ada beberapa penyalur yang menyediakan fitur yang berbeda (profil, kinerja, dll.) dan mereka membutuhkan semua alokasi untuk pergi melalui itu.
Edit: Untuk kode saya sendiri, saya akan hanya pernah melakukan itu sebagai pilihan terakhir. Dan maksud saya saya hampir akan positif tidak pernah menggunakannya. Tapi saya pribadi proyek-proyek yang jelas-jelas jauh lebih kecil/persyaratan yang sangat berbeda.
Overloading baru & menghapus memungkinkan untuk menambahkan tag ke situs alokasi memori. Saya tag alokasi per sistem atau kontrol atau oleh middleware. Aku dapat melihat, pada saat runtime, berapa banyak masing-masing kegunaan. Mungkin aku ingin melihat penggunaan parser dipisahkan dari UI atau berapa banyak bagian dari middleware adalah benar-benar menggunakan!
Anda juga dapat menggunakannya untuk menempatkan penjaga band seluruh memori yang dialokasikan. Jika/ketika anda crash aplikasi yang dapat anda lihat di alamat. Jika anda melihat isi sebagai "0xABCDABCD" (atau apa pun yang anda pilih sebagai penjaga) anda mengakses memori anda don't sendiri.
Mungkin setelah memanggil menghapus anda dapat mengisi ruang ini dengan demikian pola dikenali. Saya percaya VisualStudio melakukan sesuatu yang serupa di debug. Doesn't itu mengisi uninitialized memori dengan 0xCDCDCDCD?
Akhirnya, jika anda memiliki masalah fragmentasi anda bisa menggunakannya untuk mengarahkan ke blok pengalokasi? Saya tidak yakin seberapa sering ini adalah benar-benar masalah.
Anda perlu membebani mereka ketika panggilan baru dan menghapus doesn't bekerja di lingkungan anda.
Misalnya, dalam kernel programming, default baru dan menghapus don't bekerja karena mereka bergantung pada mode pengguna perpustakaan untuk mengalokasikan memori.
I've dilakukan dengan memori mapped file sehingga data-data yang ditulis ke memori secara otomatis juga disimpan ke disk. It's juga digunakan untuk mengembalikan memori pada alamat fisik jika anda memiliki memori mapped IO perangkat, atau kadang-kadang jika anda perlu untuk mengalokasikan suatu blok memori yang berdekatan.
Tetapi 99% dari waktu itu's dilakukan sebagai fitur debugging untuk log seberapa sering, di mana, kapan memori yang dialokasikan dan dirilis.
I've melihat hal itu dilakukan dalam sebuah sistem yang untuk 'keamanan'*
alasan-alasan yang diperlukan untuk menulis di atas semua memori yang digunakan pada de-alokasi. Pendekatan ini adalah untuk mengalokasikan tambahan beberapa byte pada awal setiap blok memori yang akan berisi ukuran keseluruhan blok yang kemudian akan ditimpa dengan nol di hapus.
Ini memiliki sejumlah masalah seperti yang anda mungkin bisa membayangkan tapi itu tidak bekerja (sebagian besar) dan menyelamatkan tim dari meninjau setiap alokasi memori yang cukup besar, aplikasi yang sudah ada.
Tentu saja tidak mengatakan bahwa itu adalah baik tapi itu mungkin salah satu yang lebih imajinatif orang-orang di luar sana...
*
sayangnya itu bukan't begitu banyak tentang keamanan yang sebenarnya sebagai penampilan keamanan...
It's benar-benar cukup umum untuk permainan untuk mengalokasikan satu besar sepotong memori dari sistem dan kemudian memberikan kustom penyalur via kelebihan beban baru dan menghapus. Salah satu alasan besar adalah bahwa konsol tetap memiliki ukuran memori, membuat kedua kebocoran dan fragmentasi masalah besar.
Biasanya (setidaknya pada platform tertutup) default operasi tumpukan datang dengan kurangnya kontrol dan kurangnya introspeksi. Untuk banyak aplikasi ini doesn't peduli, tapi untuk game berjalan secara stabil di tetap-memori situasi menambahkan kontrol dan introspeksi yang baik sangat penting.
Dari sudut pandang praktis itu hanya mungkin lebih baik untuk mengganti malloc pada sistem perpustakaan tingkat, sejak operator baru yang mungkin akan menyebutnya pula.
Pada linux, anda dapat menempatkan anda sendiri versi malloc di tempat sistem satu, seperti dalam contoh berikut:
http://developers.sun.com/solaris/articles/lib_interposers.html
Dalam artikel tersebut, mereka mencoba untuk mengumpulkan statistik kinerja. Tapi anda juga dapat mendeteksi kebocoran memori jika anda juga menimpa gratis.
Sejak anda melakukan hal ini di ruang perpustakaan dengan LD_PRELOAD, anda don't bahkan perlu mengkompilasi ulang aplikasi anda.
Ini bisa menjadi trik yang bagus untuk aplikasi anda untuk dapat menanggapi kondisi memori rendah oleh sesuatu yang lain dari sebuah kecelakaan acak. Untuk melakukan hal ini anda baru
bisa menjadi sederhana proxy default baru
yang menangkap kegagalan, membebaskan beberapa hal dan mencoba lagi.
Teknik yang paling sederhana adalah untuk memesan kosong blok memori pada waktu start-up untuk tujuan itu. Anda mungkin juga memiliki beberapa cache anda dapat menekan dalam - ide yang sama.
Ketika pertama alokasi kegagalan tendangan, anda masih memiliki waktu untuk memperingatkan pengguna tentang kondisi memori rendah ("aku'akan mampu bertahan sedikit lebih lama, tetapi anda mungkin ingin menyimpan pekerjaan anda dan menutup beberapa aplikasi lain"), menyelamatkan negara anda ke disk, beralih ke mode bertahan hidup, atau apa pun yang masuk akal dalam konteks anda.
Yang paling umum use case adalah mungkin pemeriksaan kebocoran.
Use case lain adalah ketika anda memiliki persyaratan khusus untuk alokasi memori di lingkungan anda yang tidak puas dengan standar perpustakaan yang anda gunakan, seperti, misalnya, anda perlu untuk menjamin bahwa alokasi memori adalah kunci gratis di multi threaded lingkungan.
Karena sudah banyak yang menyatakan hal ini biasanya dilakukan dalam kinerja aplikasi kritis, atau untuk dapat mengontrol memori keselarasan atau melacak memori anda. Permainan sering menggunakan custom manajer memori, terutama ketika penargetan platform tertentu/konsol.
Berikut ini adalah cukup baik blog post tentang salah satu cara untuk melakukan ini dan beberapa penalaran.
Kelebihan beban operator baru juga memungkinkan programmer untuk memeras beberapa tambahan kinerja dari program-program mereka. Misalnya, Di kelas, untuk mempercepat alokasi node baru, daftar dihapus node dipertahankan sehingga memori yang dapat digunakan kembali ketika node baru dialokasikan.Dalam hal ini, kelebihan beban menghapus operator akan menambah node ke daftar dihapus node dan kelebihan beban operator baru akan mengalokasikan memori dari daftar ini bukan dari tumpukan untuk speedup alokasi memori. Memori dari tumpukan dapat digunakan ketika daftar dihapus node kosong.