Pernah tertawa tentang “abstraksi bocor” dengan teman -teman dev Anda di sebuah konferensi? Ya, ini lucu, sampai Anda yang tersangkut debugging kebocoran memori pada jam 3 pagi, mengutuk kode Anda dan menenggak minuman energi.
Jika Anda pernah ke sana, Anda tahu perasaan tenggelam ketika aplikasi Anda mulai tersedak, dan Anda berebut untuk mencari tahu mengapa.
Kebocoran memori adalah yang terburuk. Mereka seperti kecoak di basis kode Anda, menyelinap, melahap memori sampai aplikasi Anda melambat atau hanya macet. Keras. Dan kickernya? Bahkan kode Anda yang paling bersih dan paling cemerlang dapat berubah menjadi kekacauan panas jika kebocoran keluar dari kendali.
Tapi Anda tidak harus hanya duduk di sana dan mengambilnya. Saya mendapatkan punggung Anda dengan 5 cara mati-sandaran, no-BS cara-cara untuk berbulu kode Anda terhadap kebocoran memori. Ini harus dimiliki jika Anda sedang mengerjakan aplikasi atau layanan lalu lintas tinggi yang perlu begadang selamanya. Karena, jujur, tidak ada yang peduli tentang kode sempurna Anda jika aplikasi Anda terus tanking.
Mari kita lipatkan kebocoran itu untuk selamanya. Siap?
5 Cara praktis untuk mengeraskan kode Anda terhadap kebocoran memori
1. Hindari finalisasi utama () di java
Finalisasi Java () kedengarannya berguna, tetapi dalam kenyataannya? Ini sedikit bencana di bawah kap mesin. Ini menciptakan lebih banyak masalah daripada solusi. Masalahnya adalah bahwa begitu Anda mengganti finalisasi (), Java harus bergerak melalui lingkaran tambahan. Dan ketika suatu objek memiliki metode finalisasi (), Java memasukkannya ke dalam antrian khusus, dan utas khusus menjalankannya. Hanya setelah itu, memori itu benar -benar dapat dibersihkan, dan ini menunda waktu pengumpulan sampah.
Objek dengan finalisasi () dapat memakan waktu lebih lama untuk dibersihkan, itulah sebabnya aplikasi Anda mungkin melambat tanpa peringatan. Faktanya, beberapa pengumpul sampah tidak bermain dengan baik dengan finalisasi (), yang mengarah ke lebih banyak siklus koleksi dan pekerjaan tambahan. Hasilnya? Aplikasi Anda dapat menerima pukulan.
- Implementasikan AutoCable dengan metode clean close ().
- Gunakan cobalah dengan sumber daya sehingga Java dapat menangani pembersihan secara otomatis.
- Selalu periksa ulang subkelas sehingga mereka tidak akan mewarisi finalisasi () logika secara diam-diam.
- Gunakan refreferensi lemah atau phantomreference untuk caching.
- Terus membersihkan sumber daya asli seperti pegangan dan soket file
2. Gunakan pengumpulan objek di aplikasi .net
Pooling objek adalah cara yang efektif untuk mengoptimalkan penggunaan memori dan kinerja aplikasi. Terkadang, ketika aplikasi Anda mengalami ketidakstabilan, Anda mungkin hanya perlu mengurangi bagaimana objek dibuat, digunakan, dan digunakan kembali. Ini adalah masalah yang bertujuan pengumpulan objek untuk diperbaiki. Pada intinya, pengumpulan objek adalah cara cerdas untuk menggunakan kembali objek yang ada daripada membuat yang baru dari awal.
Bagaimana ini pintar? Dengan menggunakan kembali benda -benda, tekanan pada pengumpul sampah diangkat. Dan ini hanya akan meningkatkan kinerja aplikasi yang lancar dan menghindari jeda lebih sedikit. Pendekatan ini memiliki dua manfaat tambahan: menghemat memori dan mengurangi waktu untuk mengalokasikan dan menangani sumber daya. Kedengarannya seperti win-win bagi saya.
Tidak menjadi orang yang pooper di sini. Tapi, inilah sedikit peringatan: pooling dapat memperlambat segalanya jika Anda tidak membutuhkannya. Inilah sebabnya mengapa Microsoft merekomendasikan pengujian dalam skenario kehidupan nyata sebelum diimplementasikan. Ikuti langkah -langkah ini untuk mengetahui cara mengimplementasikan pengumpulan objek di aplikasi .net Anda:
- Gunakan dotmemory atau alat profil yang efisien untuk menemukan objek yang sering dibuat, namun memiliki kehidupan singkat.
- Buat kebijakan ObjectPool khusus yang menghapus data sisa sebelum menggunakan kembali objek.
- Gunakan blok coba/akhirnya untuk memastikan benda -benda yang dipinjam dikembalikan ke kolam.
- Benchmark aplikasi Anda sebelum dan sesudah pooling untuk mengukur kinerja.
3. Eksekusi pembersihan di react evefect hooks
Ketika sesuatu mulai berjalan di latar belakang yang seharusnya tidak, aplikasi Anda kemungkinan besar akan mulai berperilaku aneh. Jenis kebocoran memori ini terjadi di aplikasi React ketika komponen berpegang pada hal -hal bahkan setelah tidak dipasang. Ini biasanya merupakan hasil dari tugas asinkron atau referensi gigih yang lebih lama dari komponen yang memulai.
Contoh umum adalah ketika pendengar peristiwa masih aktif bahkan setelah tidak adanya komponen. Contoh khas lainnya adalah langganan sumber data yang tidak pernah tidak berlangganan, bersama dengan beberapa masalah lainnya. Untungnya, React memberikan kait pembersihan, useEffect, untuk menyelesaikan masalah ini.
Sekarang, pengembang dapat menemukan cara untuk membersihkan komponen sebelum menjalankan kembali atau tidak menghitung. Manfaat fungsi ini hampir tidak ada habisnya. Akhirnya, Anda dapat menghapus timer, membatalkan langganan, dan menghapus pendengar acara. Semua dengan mengeksekusi langkah sederhana? Ya.
Tapi yang berada di puncak semuanya adalah bahwa langkah sederhana ini membebaskan memori dan membuat aplikasi Anda efisien. Ingin aplikasi React Anda stabil dari waktu ke waktu? Kemudian, pembersihan adalah suatu keharusan.
Izinkan saya menunjukkan cara melakukannya.
- useEffect (() => {…}, [ ]);
- Kait ini harus berjalan sekali setelah komponen dipasang. Ini juga tempat Anda menempatkan efek samping.
- Biarkan ismounted = true;
- Ini melacak apakah komponen masih dipasang.
- const fetchData = async () => {…}
- Ini mengambil data dari API eksternal.
- const controller = new abortController ();
- Ini membatalkan permintaan pengambilan jika komponen membuka.
- const response = menunggu fetch ('https: //api.yuandme.com/data', {sinyal});
- Ini mengirimkan permintaan HTTP yang sebenarnya ke API.
- data const = menunggu respons. json ();
- Ini menguraikan respons yang dikembalikan sebagai JSON kemudian menerima informasi yang diambil dari API
- if (isMounted) {setData (data); }
- Catch (error) {…}
- Ini menangkap dan mencatat setiap kesalahan selama pengambilan dan mengabaikan Aborterror.
- fetchdata ();
- Ini meminta fungsi async untuk memulai proses pengambilan data.
- return () => {…}
- Ini adalah fungsi pembersihan dari alat bantu yang berjalan tepat sebelum komponen tidak ada gunanya.
- ismounted = false;
- Ini memastikan bahwa kami tidak memperbarui status setelah komponen hilang.
- Controller.abort ();
- Ini membatalkan permintaan pengambilan jika masih berlangsung dan mencegah kebocoran memori.
4. Fix Equals () dan HashCode () dalam koleksi Java
Sangat mudah bagi kita untuk fokus pada hal -hal besar dalam pengembangan Java, tetapi kadang -kadang detail kecil yang menyebabkan masalah terbesar. Salah satu detail kecil itu: Penggunaan Equals () dan HashCode yang tepat (). Saya tidak akan terkejut jika Anda bertanya -tanya bagaimana metode sederhana ini dapat menyebabkan kebocoran memori.
Nah, dua metode yang tampaknya sederhana ini adalah inti dari bagaimana Java menangani objek dalam hashmap atau hashset. Dan jika diimplementasikan secara tidak benar? Segalanya mungkin menurun.
Banyak pengembang tergelincir dengan overriding equals () dan lupa untuk mengganti kode hashcode (). Ini akan menghasilkan koleksi yang menerima dan menyimpan duplikat. Seiring waktu, aplikasi akan bertahan pada objek yang seharusnya tidak. Hasilnya? Memori kembung. Ini tidak akan segera merusak aplikasi Anda, tetapi itu akan membuatnya tidak responsif.
- @0Verride Public Boolean Equals (0bject o) {/*…*/} @0Verride public int hashCode () {/*…*/}
- Lakukan dengan baik untuk mengesampingkan kedua metode bersama dan bukan hanya satu metode.
- return 0bjects .hash (id, name); // bidang yang sama sebagai Equals ()
- Lakukan dengan baik untuk membuat HashCode () hasil pengembalian yang konsisten untuk objek yang sama.
- nama string final pribadi; // Bidang Immutable Digunakan di Equals/HashCode
- Berhati -hatilah untuk menggunakan bidang yang tidak dapat diubah untuk perhitungan.
- sama: return this.id == o.id; HashCode: return integer.hashcode (id);
- Sertakan bidang yang tepat di kedua metode.
- Gunakan referensi yang lemah untuk manajemen cache
Manajemen memori sering muncul sebagai perhatian saat membangun cache. Tentu saja, tidak ada pengembang yang ingin aplikasi mereka bertahan lebih lama dari yang seharusnya. Di situlah referensi yang lemah masuk. Mengapa referensi lemah sangat berharga dalam mengelola cache?
Nah, semuanya bermuara pada kemampuan mereka untuk memungkinkan memori direklamasi terutama ketika itu tidak digunakan. Ini berarti bahwa jika memori tidak digunakan, itu dapat dibersihkan dan referensi dapat dibersihkan.
Sangat penting untuk dicatat bahwa platform yang berbeda menawarkan berbagai referensi lemah. Dalam JavaScript, lemah dan lemah selalu berguna. Weakmap sangat cocok untuk melampirkan metadata sementara ke benda tanpa mempengaruhi umur mereka dalam memori.
Di sisi lain, lemah sangat ideal saat mengelompokkan objek yang Anda tidak perlu ingin tetap hidup. Dan di Java, Lemah Referensi sangat bagus ketika membangun koleksi yang memegang benda hanya ketika aplikasi sampai membutuhkannya.
Pikiran terakhir
Satu kebenaran yang sulit? Mencegah kebocoran memori bukanlah sesuatu yang Anda lakukan sekali dan lupa. Anda harus membangunnya ke dalam cara Anda mengkode, menguji, dan menggunakan. Ini juga membutuhkan konsistensi, jadi Anda tidak bisa hanya pergi seminggu dengan kebocoran heroik dan kembali ke kebiasaan lama.
Tim yang menerapkan praktik manajemen memori yang baik ini yang telah saya bagikan dijamin memiliki aplikasi yang berkembang. Pada akhirnya, ini adalah aplikasi yang tahan lama dan berkembang yang akan dihargai.