เคยเขียนไปบ้างแล้วเกี่ยวกับ Reference ต่างๆ ใ น Flex ว่าควรจะใช้ Weak reference ให้หมดเมื่อมีการเพิ่ม EventListener ต่างๆ เข้าไปแต่เมื่อสองวันก่อนก็เจอเหตุไม่คาดฝันเข้าเพราะกำลังสร้าง Mock แล้วทดสอบปรากฏว่าฟังก์ชั่น ที่มันควรจะทำมันดันถูกลบไปก่อน
เหตุผลก็เนื่องจากว่า ก่อนที่ Flex จะวาดอะไรก็ตามมันจะไปเรียก Garbage collector มาเก็บกวาดทีนึง ดังนั้น หากมีการใช้ Weak reference ก่อนขั้นตอนนี้ซึ่งก็คือ ก่อน Commit properties วัตถุต่างๆ จะถูกกวาดไปจนหมดก่อนที่จะได้วาดออกมาเป็นภาพ
วันนั้นก็นั่งแก้ นั่งงง แล้วก็ลองส่งข้อความไปใน twetter ดูแล้วก็เหมือนเกิดเป็นหัวข้อใหม่ คุยกับ @iporsut เกี่ยวกับเรื่องนี้ยาวพอสมควร(ยาวสำหรับผมนะ ;p คนอื่นอาจเห็นว่าไม่ยาว) แล้ว @iporsut ก็ได้ข้อสรุปมาว่า Weak reference นั้นไว้แก้ปัญหาเรื่อง Circular reference (การอ้างอิงวัตถุวนไปวนมา)
จริงๆ @iporsut ยังไม่ได้เขียนสรุปอะไรมากหรอก แต่ผมก็เคยอ่านแล้วหละ ว่า Garbage collector ของ Flex นั้นมีการทำงานอยู่สองแบบคือ Reference count กับ Sweep อย่างแรกคือ ถ้าวัตถุไหนไม่มีการอ้างอิงใดๆ จากวัตถุอื่นเลยก็จะถูกเก็บไป แต่ปัญหามันจะเกิดเมื่อมี วัตถุที่ Reference กันเองเป็นวงกลม ทำให้ Garbage collector พอนับจำนวน reference แล้วไม่สามารถเก็บวัตถุทั้งสองอันนั้นได้ ดังนั้นเลยมี Weak reference ขึ้นมาเพื่อให้ Garbage collector รู้ว่า reference นี้ไม่ต้องนับหากจะเตรียมเก็บ วัตถุต่างๆไปทิ้ง
สำหรับอีกอันนึงที่ Flex ใช้ก็คือ Garbage collector จะเริ่มดูว่างจากจุดเริ่มต้นของโปรแกรม มีวัตถุไหนที่เชื่อมโยงกันอยู่บ้าง ถ้าอันไหนไม่มี reference กับอันหลักแล้วแม่จะยังมี จำนวน reference มากกว่า 0 อยู่ ก็จะถูกเก็บไปทั้งหมดอยู่ดี ซึ่งวิธีนี้มันก็มีปัญหากับ object ที่เกี่ยวกับ data service อยู่ดี เพราะพวกนี้จะมีการอ้างอิงตลอด ในหลายเว็บก็มีการแนะนำว่า ให้กำหนดช่วงที่ component นั้นถูกลบไปเลยให้ลบ event listener ออกจาก data service ด้วย แต่ Flex มันไม่มีอะไรที่คล้ายๆ finalize หรือ delete ของ java หรือ c++ นี่สิ (หรือมีหว่า) ดังนั้นหากจะ กำนหนดเป็น interface แล้ว implement ขึ้นมาเองทุก component ก็ยังไงอยู่
ดังนั้นหากอะไรที่เป็น UI ก็ควรจะใช้ hard reference ธรรมดาไป เพราะว่าพวกนี้จะถูกลบโดย Garbage collector วิธีที่สองอยู่แล้วแต่ service ต่างๆ ถ้าไม่อยากลบเองก็ใช้ weak reference ละกันครับ เพราะว่าการ เรียกแล้วดึงข้อมูลมาใหม่เพื่อ redraw(Update display list) มันไม่ถือว่าเป็นการวาด component ใหม่หมด ดังนั้น Garbage collector เลยยังไม่ถูกเรียกมาเพื่อเก็บกวาด reference ของ service ต่างๆ ก็เลยยังทำงานอยู่อย่างปกติ
โอ่ย ยาว อีกนิดละกัน ตัวอย่างที่ทำให้ผมรู้ว่า reference ต่างๆ เป็นยังไง
โค้ดที่เขียนออกมาเป็นด้านบน: source code
อ้างอิง: Understand flash garbage collector
เพิ่มเติม: @iporsut ส่ง link ที่จำลองการทำงานของ Garbage collector ใน Flex มาให้เลยเอามาใส่เพิ่มซะ หน่อย ^^!
เขียนเมื่อ: June 11th, 2008 | หมวด: ภาษาเครื่องกล | แถก: Flex,garbage collector | อ้างอิง |




