Rumah >pembangunan bahagian belakang >tutorial php >PHP Master | Lebih baik memahami koleksi sampah php
mata teras:
Program dihasilkan sampah
Program menggunakan sumber, kadang -kadang sumber kecil, kadang -kadang sumber yang besar. Sebagai contoh, medan data. Program boleh menentukan medan data (seperti nombor siri) dan menggunakannya dalam program. Setelah ditakrifkan, medan data ini akan mengambil ruang ingatan, mungkin hanya beberapa bait, tetapi masih ruang. Oleh kerana setiap persekitaran mesin atau pengaturcaraan mempunyai ruang yang terhad, ruang yang tinggal akan mengurangkan jumlah ruang yang diduduki oleh bidang ini. Apabila program berakhir, program dan mana -mana ruang yang digunakan akan hilang dan jumlah ruang yang tersedia akan dipulihkan kepada saiz maksimumnya. Tetapi apa yang berlaku jika program tidak pernah berakhir? Saya telah menulis beberapa program ini sebelum ini. Mereka adalah karya -karya yang indah dan saya sentiasa gembira apabila orang lain dalam notis bengkel yang saya buat. Tidak ada yang menunjukkan kebolehan anda lebih baik daripada mempunyai komputer IBM yang besar di bawah anda sendiri, dan di dalam petak sekitarnya, satu orang selepas teriakan lain, "Hei, ada sesuatu yang salah dengan sistem?" mengalihkan perhatian dari anda. Tetapi sesetengah program juga direka untuk berjalan selama -lamanya, seperti daemon dan program -program lain. Ketika mereka berjalan, jumlah sampah yang mereka hasilkan dapat terus berkembang. Jika sumber terkunci adalah besar, ia akan mempunyai kesan negatif yang nyata terhadap sistem. Oleh itu, setiap bahasa mesti mempunyai cara untuk membersihkan sumber -sumber yatim, menjadikannya tersedia untuk pengguna lain, dan memastikan jumlah ruang sistem yang ada tetap sama. Nasib baik, PHP menggunakan kaedah tiga lapisan untuk penyingkiran sampah.
lapisan pertama skop
Pertama sekali, seperti kebanyakan bahasa, apabila skop berakhir, segala -galanya dalam skop itu dimusnahkan dan sebarang sumber yang diperuntukkan dibebaskan. Skop boleh meliputi fungsi, skrip, sesi, dan lain -lain. Apabila skop berakhir, segala yang dipegangnya berakhir dengannya. Sudah tentu, anda boleh membebaskan sumber pada bila -bila masa menggunakan fungsi Unset (). Ini adalah salah satu sebab fungsi dan kaedah sangat penting kerana mereka menubuhkan skop, menentukan apabila penggunaan memori tertentu bermula dan berakhir, dan menghadkan berapa lama perkara wujud. Mereka harus digunakan di mana mungkin, bukan entiti global.
kiraan lapisan kedua -
Kedua, seperti kebanyakan bahasa skrip, PHP menggunakan teknik yang dipanggil Rujukan Count untuk mengesan berapa entiti menggunakan pembolehubah yang diberikan. Apabila membuat pemboleh ubah dalam skrip PHP, PHP mencipta "bekas" kecil yang dinamakan ZVAL yang terdiri daripada nilai yang diberikan kepada pembolehubah ditambah dua maklumat lain: IS_REF dan RefCount. Bekas zval disimpan dalam jadual, dan setiap skop (skrip, fungsi, kaedah, dll) mempunyai jadual. IS_REF adalah nilai sebenar/palsu yang menunjukkan sama ada pembolehubah adalah sebahagian daripada set rujukan, dengan itu membantu PHP menentukan sama ada ia adalah pembolehubah mudah atau rujukan. RefCount lebih menarik kerana ia memegang nilai angka yang menunjukkan berapa banyak pembolehubah yang berbeza menggunakan nilai ini. Iaitu, jika anda menentukan pembolehubah $ Dave = 6, refcount akan ditetapkan kepada 1. Jika saya katakan $ Programmer = $ Dave, RefCount akan ditingkatkan kepada 2. PHP tidak tahu untuk membuat zval kedua untuk nilai 6; Refcount ini akan menurun apabila program berakhir, sama ada apabila kita meninggalkan skop fungsi, atau apabila menggunakan UNSET (). Apabila refcount mencapai sifar, zval akan dimusnahkan dan apa -apa ingatan yang dipegangnya kini dibebaskan. Sudah tentu, ini adalah contoh mudah pemboleh ubah yang mudah. Apabila anda bercakap tentang array atau objek, keadaannya lebih rumit kerana pelbagai Zrefs akan dibuat untuk pelbagai nilai elemen dalam array, tetapi pemprosesan asas adalah sama. Walau bagaimanapun, jika kita menggunakan tatasusunan dalam array lain, yang sering berlaku dalam skrip PHP yang lebih kompleks, masalah timbul. Dalam kes ini, apabila nilai tatasusunan asal ditetapkan, refleksi nilai array ditetapkan kepada 1, dan kemudian apabila array dikaitkan dengan array lain, refcount ditingkatkan kepada 2. Jika pelbagai penggunaan array kedua berakhir, refcount diturunkan oleh 1. Kami kini berada dalam situasi di mana nilai itu sendiri tidak lagi dikaitkan dengan apa -apa, tetapi refleksi bekas (zval) yang mewakili ia masih lebih besar daripada sifar. Hasil akhirnya adalah bahawa storan yang diwakili oleh array asal tidak akan dibebaskan dan jumlah memori kini tidak tersedia untuk apa -apa. Sering kali, kita fikir penyimpanan yang hilang ini kecil, tetapi biasanya tidak berlaku. Arrays boleh menjadi perkara yang sangat besar pada hari ini, dan ia amat bermasalah jika skrip yang berlaku adalah daemon atau fungsi lain yang berjalan hampir berterusan. Dalam kes ini, "kebocoran memori" yang terhasil boleh membawa kesan bencana untuk prestasi dan juga keupayaan operasi pelayan.
Kitar semula sampah formal lantai ketiga
Jelas sekali, penjelasan berdasarkan kiraan rujukan mempunyai batasannya, tetapi bernasib baik, Php 5.3 menyediakan pilihan lain untuk membantu dengan keadaan ini. Kes khusus yang kita mahu kitaran pengumpulan sampah diselesaikan adalah kes di mana zval menurun tetapi masih tidak sifar. Pada asasnya, gelung untuk melihat nilai mana yang boleh diturunkan dan kemudian melepaskan nilai dengan sifar. Apa yang sebenarnya berlaku ialah PHP menjejaki semua bekas akar (ZVAL). Ini dilakukan tanpa mengira sama ada pengumpulan sampah berada atau tidak (kerana ia hanya perlu melakukan ini tanpa bertanya sama ada pengumpulan sampah dihidupkan atau tidak, dll.). Penampan akar ini boleh memegang sehingga 10,000 akar (saiz tetap, tetapi ini boleh diubah). Apabila ia mengisi, mekanisme pengumpulan sampah akan bermula dan mula menganalisis penampan ini. Perkara pertama yang dilakukan oleh rutin GC adalah meleleh melalui penampan akar dan pengurangan semua kiraan zval sebanyak 1. Apabila melakukan ini, ia menandakan setiap tag dengan tag kecil seperti tanda semak supaya ia menurunkan akar sekali sahaja. Ia kemudian melangkah ke atas dan menandakan (kali ini menggunakan garis bergelombang kecil) semua zvals yang dikurangkannya adalah sifar. Nilai-nilai yang tidak sifar akan meningkat sehingga mereka kembali ke nilai asalnya. Akhirnya, ia akan menatal lagi, jelas zval bukan sifar dari penampan, dan membebaskan kedai dengan nilai sifar refcount. Pengumpulan sampah sentiasa didayakan dalam PHP, tetapi anda boleh mematikannya menggunakan arahan zend.enable_gc dalam fail php.ini. Sebagai alternatif, anda boleh melakukan ini dalam skrip dengan memanggil fungsi gc_enable () dan gc_disable (). Seperti yang disebutkan di atas, jika pengumpulan sampah diaktifkan, ia berjalan apabila akar penuh, tetapi anda boleh mengatasi tetapan ini dan menjalankan koleksi menggunakan fungsi gc_collect_cycles () apabila anda melihat patut. Dan, anda boleh mengubah saiz penampan akar menggunakan nilai gc_root_buffer_max_entries dalam zend/zend_gc.c dalam kod sumber php. Segala-galanya, ini membolehkan anda mengawal sama ada dan kapan dan di mana GC berjalan, yang merupakan perkara yang baik kerana ia adalah sedikit sumber-intensif dan oleh itu mungkin bukan jenis perkara yang anda jalankan.
bila menggunakannya
Oleh kerana pengumpulan sampah boleh menjejaskan prestasi, ia perlu mengambil masa untuk menentukan bila anda perlu menggunakannya. Mula -mula, ingatlah bahawa melainkan jika anda menjalankannya secara terbuka (menggunakan fungsi GC_Collect_Cycles ()), pengumpulan sampah rasmi tidak berlaku sebelum jadual akar (10,000 penyertaan) mengisi, dan kerana jadual ini berada pada tahap skop, untuk kecil ini menang ' t berlaku dengan fungsi. Sekiranya anda menggunakannya pada skrip kecil? Terpulang kepada anda. Sukar untuk mengatakan bahawa operasi berjalan seperti koleksi sampah adalah perkara yang buruk, tetapi jika anda mempunyai skrip kecil, cepat berjalan yang bermula dan berakhir dan hilang, mungkin tidak banyak ganjaran. Walau bagaimanapun, jika pelayan anda menjalankan banyak skrip kecil yang tetap berterusan, ia mungkin bernilai usaha. Satu -satunya cara untuk benar -benar tahu ialah menetapkan penanda aras untuk permohonan anda dan melihatnya. Sudah tentu, jika anda mempunyai skrip jangka panjang, terutama yang tidak pernah berakhir, maka pengumpulan sampah adalah penting jika anda ingin menghalang kebocoran memori yang dibincangkan di atas. Mungkin yang paling penting, kita harus sentiasa berusaha mengikuti panduan pengaturcaraan yang baik supaya kita meminimumkan atau menghapuskan pembolehubah global dan mengikat pembolehubah kita untuk skop sehingga walaupun kita telah lama menjalankan skrip, kita ingatan ini dapat dibebaskan pada akhir fungsi, tidak pada akhir skrip. Juga sedar apabila objek rujukan array atau objek digunakan dalam array, kerana situasi ini boleh menyebabkan kebocoran ingatan dan merupakan matlamat sebenar proses pengumpulan sampah rasmi.
Gambar dari Fotolia
FAQ Kitar Semula PHP (FAQ)
Atas ialah kandungan terperinci PHP Master | Lebih baik memahami koleksi sampah php. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!