Archive

Archive for June, 2014

ประเภทของ Object ใน Java Virtual Machine และ Common Language Runtime

ใน Java Virtual Machine (JVM) และ Common Language Runtime (CLR) นั้น จะมี Type อยู่สองประเภทคือ Value Type และ Reference Type ซึ่ง Value Type จะเป็น Type ที่ Object จะเกิดการ Copy ตัวมันเองเมื่อมีการ Assign ตัวมันให้กับตัวแปรอื่น ส่วน Reference Type จะเป็น Type ที่ Object อาศัยอยู่บน Heap เท่านั้น ซึ่งต้องใช้ new ในการสร้างขึ้นมา

ใน JVM นั้น เราไม่สามารถสร้าง Value Type เพิ่มได้ ต้องใช้อันมี่ทีอยู่แล้วเท่านั้น ซึ่งแตกต่างจาก CLR ที่เราสามารถสร้าง Value Type เพิ่มได้ ทำให้ CLR มีข้อได้เปรียบอยู่หลายอย่าง เช่น

  • Performance ที่เพิ่มขึ้น เนื่องจาก Value Type ไม่จำเป็นต้องจอง Memory บน Heap
  • ติดต่อกับ Native Code ได้ง่ายขึ้น เนื่องจาก Type ใน Native Code จะเป็น Value Type

Object ที่เป็นชนิด Value Type นั้นสามารถแปลงเป็น Reference Type ได้ด้วยการ Wrap ไว้ใน Object ที่เป็น Reference Type อีกทีหนึ่ง ซึ่งการ Wrap นี่จะเรียกว่า “Boxing” ส่วนการแปลงกลับมาเป็น Value Type อีกครั้งจะเรียกว่า “Unboxing”

การ Boxing นั้น ใน C# จะสามารถ Assign ตัว Object ที่เป็นประเภท Value Type ใส่ตัวแปรที่เป็นคลาส System.Object ได้ทันที การ Unboxing นั้นก็เหมือนกัน สามารถ Cast กลับมาได้ทันที ส่วน Java นั้นเราจำเป็นต้องใช้คลาสที่มีมาให้อยู่แล้ว เช่น java.lang.Integer สำหรับ Wrap ตัว Object ที่เป็นชนิด int

Advertisements

ว่าด้วยเรื่องของ Asynchronous I/O บน Unix และ Win32

Asynchronous I/O ที่ใช้กันส่วนใหญ่ในปัจจุบันจะมีอยู่สองแบบ คือ แบบเก่าที่เป็นแบบ Notify on Ready และแบบใหม่ที่เป็นแบบ Notify on Completion ซึ่งต่อไปนี้จะขอเรียกว่า NoR และ NoC

NoR นั้นได้ถูกคิดค้นขึ้นมาก่อน NoC สำหรับใช้บน Unix ในช่วงแรกๆ ส่วน NoC นั้นได้ถูกคิดค้นขึ้นมาสำหรับใช้กับ Windows NT ซึงถูกเรียกว่า Overlapped I/O (แต่ก็ยังคงรองรับ NoR)

NoR นั้นจะใช้การแจ้งเตือนเมื่อ I/O พร้อมที่จะทำงาน เช่น มีข้อมูลสำหรับอ่านแล้ว หรือมี Buffer ว่างสำหรับทำการเขียน ข้อดีคือ เขียนได้ง่ายกว่าแบบ NoC ส่วนข้อเสียคือ

  • จัดการกับ Error ที่เกิดขึ้นจากการเขียนได้ยากมาก เนื่องจากเราเขียนลง Buffer ของ Kernel ไม่ใช่การเขียนลง Device จริง
  • อ่านพร้อมกันมากกว่าหนึ่งเธรดลำบาก เนื่องจากต้องมีการ Synchronize เพื่อป้องกันไม่ให้เธรดอื่นเข้ามาอ่านในระหว่างที่อีกเธรดกำลังอ่านอยู่ ซึ่งก็ไม่ใช่วิธีที่ดีเพราะจะก่อให้เกิดการ Lock เกิดขึ้น

ส่วน NoC นั้นจะใช้การแจ้งเตือนเมื่อ I/O ทำงานเสร็จแล้ว เช่น เราสั่งอ่านข้อมูล เมื่อการอ่านเสร็จสิ้น ก็จะมีการแจ้งเตือนมาบอกว่าอ่านเสร็จแล้ว การเขียนก็เหมือนกัน เราสั่งเขียน เมื่อการเขียนเสร็จสิ้น ก็จะมีการแจ้งเตือนมาบอกว่าเขียนเสร็จแล้ว มีข้อดีคือ

  • ใช้ได้มากกว่าหนึ่งเธรด เนื่องจากมีการกำหนด Buffer ที่จะทำการอ่านหรือเขียนตอนสั่ง I/O พอ I/O ทำงานเสร็จสิ้น การแจ้งเตือนจะตกไปอยู่ที่เธรดไหนก็ได้ไม่จำเป็นต้องเป็นเธรดที่สั่ง I/O
  • จัดการกับ Error ที่เกิดขึ้นกับ Device ได้ง่าย เนื่องจากการแจ้งเตือนจะถูกส่งมาหลังจากทำงานเสร็จสิ้นหรือมี Error เกิดขึ้นเท่านั้น

ส่วนข้อเสียคือ

  • เขียนได้ยากกว่าแบบ NoR เนื่องจากต้องมีการจัดการกับ Buffer ที่ยังทำงานไม่เสร็จ
  • พอร์ต Code เก่าๆที่เขียนโดยใช้ NoR ได้ยาก เนื่องจากรูปแบบที่แตกต่างกัน

ใน Unix และ Unix-like ใหม่ๆนั้นส่วนใหญ่จะรองรับ NoC กันหมดแล้ว แต่บาง OS ก็ยังไม่สมบูรณ์ บวกกับแต่ละ OS มี API ที่แตกต่างกัน ทำให้หากต้องการเขียน Code ที่ใช้ NoC บนหลายๆ OS ที่เป็น Unix และ Unix-like นั้นจะยุ่งยากมาก เลยไม่ค่อยเป็นที่นิยม ทำให้ส่วนใหญ่ยังคงใช้แบบ NoR กันอยู่ ส่วนบน Windows NT นั้น I/O ทุกอย่างจะใช้ NoC ทั้งหมด แล้วค่อยทำแบบ Synchronous โดยขี่อยู่บน Asynchronous อีกทีหนึ่ง ซึ่งการรองรับ NoR บน Windows NT นั้นทำขึ้นมาเพียงเพื่อให้ API บางส่วนเกิดความเข้ากันได้กับฝั่ง Unix เท่านั้น