หากคุณสงสัยว่าเกิดอะไรขึ้นกับแอปพลิเคชัน 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 ไปลองใช้ดูและแจ้งให้เราทราบหากคุณพบสิ่งที่น่าสนใจ!
อย่าลืมแชร์โพสต์นี้กับเพื่อนโปรแกรมเมอร์ของคุณทุกคน มันจะช่วยให้พวกเขาได้เรียนรู้สิ่งใหม่ &มันจะช่วยให้ฉันได้รับผู้อ่านมากขึ้น 🙂