หากคุณสงสัยว่าเกิดอะไรขึ้นกับแอปพลิเคชัน Ruby ของคุณ…
ไม่มีเครื่องมือ GUI แฟนซี …
แต่เรามีโมดูล ObjectSpace!
ObjectSpace ให้ข้อมูลเกี่ยวกับสถานะปัจจุบันของใบสมัครของคุณ
มาดูกันว่ามันทำงานอย่างไร
การนับวัตถุ
การใช้ ObjectSpace
คุณสามารถทราบได้ว่าอ็อบเจกต์ใดที่ "มีชีวิต" อยู่ในโปรแกรมของคุณ
วัตถุที่ยังมีชีวิตอยู่หมายความว่าอย่างไร
วัตถุยังมีชีวิตอยู่ตราบเท่าที่มีการอ้างอิงใด ๆ ที่ชี้ไปที่วัตถุนั้น การอ้างอิงเป็นเพียงวิธีการเข้าถึงวัตถุ เช่น ตัวแปรหรือค่าคงที่
หากเข้าถึงวัตถุไม่ได้ แสดงว่าสามารถลบออกจากหน่วยความจำได้อย่างปลอดภัย
ตัวอย่าง :
# The variable 'name' holds a reference to the string 'Dave'. name = 'Dave' # The 'name' variable now points to 'John'. # 'Dave' no longer has a reference pointing to it. name = 'John'
มาดูตัวอย่าง ObjectSpace
ในการดำเนินการ:
require 'objspace' # This is valid Ruby syntax, but doesn't work on irb/pry ObjectSpace .each_object .inject(Hash.new 0) { |h,o| h[o.class] += 1; h } .sort_by { |k,v| -v } .take(10) .each { |klass, count| puts "#{count.to_s.ljust(10)} #{klass}" } # Copy & paste version (use this for irb/pry) ObjectSpace.each_object.inject(Hash.new 0) { |h,o| h[o.class] += 1; h }.sort_by { |k,v| -v }.take(10).each { |klass, count| puts "#{count.to_s.ljust(10)} #{klass}" }
การดำเนินการนี้จะพิมพ์ตารางที่มีจำนวนอ็อบเจ็กต์สำหรับชั้นเรียน 10 อันดับแรกของคุณ
Count Class ------------------------- 5436 String 315 Class 251 Array 101 Encoding 69 Regexp 45 Hash 26 Module 25 Gem::Version 22 Gem::StubSpecification::StubLine 22 Gem::StubSpecification
หากคุณสงสัยว่าหน่วยความจำรั่ว คุณสามารถบันทึกข้อมูลนี้ทุก ๆ ชั่วโมง และดูว่ามีการนับวัตถุบางอย่างที่เพิ่มขึ้นตลอดเวลาแต่ไม่เคยลดลงเลย
สนุกกับวัตถุ
เมื่อใช้ ObjectSpace
คุณเข้าถึงวัตถุจริงได้ ไม่ใช่แค่ข้อมูลเกี่ยวกับวัตถุ ดังนั้นคุณจึงสามารถทำอะไรสนุกๆ ได้ เช่น พิมพ์ค่าของสตริงทั้งหมดหรือพิมพ์เส้นทางของ File
ทั้งหมดของคุณ วัตถุ
ตัวอย่าง :
ObjectSpace .each_object(String) .sort_by { |s| s.size } .each { |s| p s }
การดำเนินการนี้จะพิมพ์สตริงในหน่วยความจำทั้งหมด จัดเรียงตามขนาด คุณจะสังเกตเห็นว่ามีสตริงมากมายที่คุณไม่ได้สร้างขึ้นเอง โดยล่าม Ruby สร้างขึ้น
การใช้งานจริงหรือไม่
นี่เป็นส่วนใหญ่สำหรับการดีบักและรวบรวมสถิติเกี่ยวกับแอปของคุณ 🙂
ขนาดหน่วยความจำวัตถุ
สิ่งที่คุณทำได้อีกอย่างคือใช้ ObjectSpace.memsize_of
เพื่อค้นหาขนาดหน่วยความจำของวัตถุเฉพาะ
ตัวอย่าง :
o = "a" * 100 ObjectSpace.memsize_of(o)
สิ่งหนึ่งที่ควรคำนึงถึงคือคำเตือนจากเอกสารประกอบ:
“โปรดทราบว่าขนาดส่งคืนไม่สมบูรณ์ คุณต้องจัดการกับข้อมูลนี้เป็นเพียงคำแนะนำ”
หากคุณลองใช้วิธีนี้กับวัตถุประเภทต่างๆ คุณจะพบกับสิ่งที่น่าสนใจ เช่น Fixnum
s คืนค่า 0 เสมอ
ObjectSpace.memsize_of(42) # 0
เหตุผลก็คือ Ruby ไม่ได้สร้าง Fixnum
. ภายใน วัตถุ คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งนี้ในโพสต์ที่ฉันเขียนเกี่ยวกับตัวเลขใน Ruby
สิ่งที่น่าสนใจอีกอย่างหนึ่งคือสตริง:
ObjectSpace.memsize_of("A" * 22) # 40 ObjectSpace.memsize_of("A" * 23) # 40 ObjectSpace.memsize_of("A" * 24) # 65
ฉันใช้
"A" * size
เพื่อสร้างสายให้ยาวขึ้นโดยไม่ต้องพิมพ์ออกมา 🙂
รอ! เกิดอะไรขึ้น?
ปรากฎว่า Ruby มีการเพิ่มประสิทธิภาพในตัวสำหรับสตริงที่มีขนาดเล็กกว่า 24 อักขระ นั่นเป็นสาเหตุที่มีการใช้หน่วยความจำเพิ่มขึ้นหลังจากนั้น คุณสามารถดูรายละเอียดเพิ่มเติมได้ในโพสต์นี้จาก Pat Shaughnessy
วิธีค้นหาวิธีนามแฝง
คงจะดีไม่น้อยหากมีรายการ "ต้นแบบ" ของวิธีการนามแฝงทั้งหมดใน Ruby
ได้รับความปรารถนา!
ดูสิ่งนี้ :
class Module def aliased_methods instance_methods(false) .group_by { |m| instance_method(m) } .map(&:last) .keep_if { |symbols| symbols.length > 1 } end end
ฉันได้รับรหัสนี้จากคำตอบ Stackoverflow มันกำหนด aliased_methods
วิธีการใน Module
คลาสซึ่งใช้ instance_methods
เมธอดเพื่อรับรายการเมธอดอินสแตนซ์ทั้งหมดที่กำหนดไว้ในคลาส
ฉันรู้ว่าอาจฟังดูสับสนเล็กน้อย แต่นั่นเป็นเมตาโปรแกรมเมอร์สำหรับคุณ!
นี่คือโค้ดที่เหลือซึ่งสร้างอาร์เรย์ของชื่อคลาสทั้งหมดที่มีอ็อบเจ็กต์ 'alive' อย่างน้อยหนึ่งรายการ จากนั้นจะเรียก aliased_methods
ในทุกชั้นเรียน &พิมพ์ผลลัพธ์
objects = ObjectSpace.each_object.map(&:class).uniq objects.each do |klass| methods = "n#{klass}n#{'-'*20}n" klass.send(:aliased_methods).each do |m1, m2| methods << "#{m1.to_s.ljust(15)} #{m2}n" end puts methods end
นี่คือสิ่งที่ผลลัพธ์ออกมา :
Array -------------------- inspect to_s [] slice length size find_index index collect map collect! map!
บทสรุป
ฉันหวังว่าคุณจะสนุกกับการเรียนรู้เกี่ยวกับสิ่งเจ๋งๆ ที่คุณสามารถทำได้ด้วย ObjectSpace
ไปลองใช้ดูและแจ้งให้เราทราบหากคุณพบสิ่งที่น่าสนใจ!
อย่าลืมแชร์โพสต์นี้กับเพื่อนโปรแกรมเมอร์ของคุณทุกคน มันจะช่วยให้พวกเขาได้เรียนรู้สิ่งใหม่ &มันจะช่วยให้ฉันได้รับผู้อ่านมากขึ้น 🙂