ความแตกต่างระหว่าง“ on-heap” และ“ off-heap”


145

Ehcache พูดถึงหน่วยความจำแบบ on-heap และ off-heap อะไรคือความแตกต่าง? JVM args ใดที่ใช้เพื่อกำหนดค่า


สำหรับวิธีการใช้หน่วยความจำแบบ off-heap โปรดดู: stackoverflow.com/a/30027374/895245
Ciro Santilli 郝海东冠状病病六四事件法轮功

คำตอบ:


169

ที่เก็บบน heap หมายถึงวัตถุที่จะมีอยู่ใน Java heap (และยังขึ้นอยู่กับ GC) ในทางกลับกันที่เก็บ off-heap อ้างถึงวัตถุ (ต่อเนื่อง) ที่จัดการโดย EHCache แต่เก็บไว้นอก heap (และไม่รวมอยู่ใน GC) เนื่องจากที่เก็บ off-heap ยังคงได้รับการจัดการในหน่วยความจำมันจะช้ากว่าร้านค้าแบบ on-heap เล็กน้อย แต่ก็ยังเร็วกว่าที่เก็บดิสก์

รายละเอียดภายในที่เกี่ยวข้องกับการจัดการและการใช้งานของ off-heap store นั้นไม่ปรากฏในลิงก์ที่โพสต์ในคำถามดังนั้นจึงควรตรวจสอบรายละเอียดของTerracotta BigMemoryซึ่งใช้สำหรับจัดการ off-disk เก็บ. BigMemory (off-heap store) จะถูกใช้เพื่อหลีกเลี่ยงโอเวอร์เฮดของ GC ในฮีปที่มีหลายเมกะไบต์หรือกิกะไบต์ใหญ่ BigMemory ใช้พื้นที่ที่อยู่หน่วยความจำของกระบวนการ JVM ผ่านByteBuffers โดยตรงที่ไม่อยู่ภายใต้ GC ซึ่งแตกต่างจากวัตถุ Java ดั้งเดิมอื่น ๆ


18
+1 สำหรับการกล่าวถึง ByteBuffers โดยตรงสำหรับการสำรวจเพิ่มเติม)
สูงสุด

3
Direct ByteBuffers เสนอการเข้าถึงหน่วยความจำที่ไม่มีการจัดการ แต่ขึ้นอยู่กับ GC (ซึ่งตรงข้ามกับข้อมูลที่ชี้ไป) สิ่งนี้มีความสำคัญเนื่องจาก Direct ByteBuffer (ชนิด ByteBuffer.allocateDirect ไม่ใช่ชนิด MMap) จะถูกรวบรวมโดย GC และเมื่อได้รับการรวบรวมแล้ว Deallocater จะถูกเรียกใช้และรวบรวมหน่วยความจำที่ไม่มีการจัดการอย่างมีประสิทธิภาพเช่นกัน
Nitsan Wakart

การใช้ Unsafe เพื่อจัดสรรวัตถุดูเหมือนว่าจะมีประสิทธิภาพในการอ่านและเขียนมากกว่า Onheap / DirectByteBuffers / ByteBuffers ashkrit.blogspot.com/2013/07/…
Joe C

98

จากhttp://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

Heap-Offloading คืออะไร

โดยปกติวัตถุที่ไม่ใช่ชั่วคราวทั้งหมดที่คุณจัดสรรจะได้รับการจัดการโดยตัวรวบรวมขยะของ java แม้ว่า VM จะทำงานได้ดีในการเก็บรวบรวมขยะ แต่ ณ จุดหนึ่ง VM ก็ต้องทำสิ่งที่เรียกว่า 'Full GC' GC เต็มรูปแบบเกี่ยวข้องกับการสแกน Heap ที่จัดสรรสมบูรณ์ซึ่งหมายความว่า GC การหยุดชั่วคราว / การชะลอตัวเป็นสัดส่วนกับขนาดฮีปของแอปพลิเคชัน ดังนั้นอย่าเชื่อถือใครก็ตามที่บอกคุณว่า 'ความจำราคาถูก' ในการใช้หน่วยความจำจาวาเจ็บประสิทธิภาพ นอกจากนี้คุณอาจได้หยุดชั่วคราวด้วยขนาดฮีป> 1 Gb สิ่งนี้อาจน่ารังเกียจหากคุณมีสิ่งที่เกิดขึ้นแบบเรียลไทม์ในคลัสเตอร์หรือกริดกระบวนการ java อาจไม่ตอบสนองและหลุดออกจากคลัสเตอร์

อย่างไรก็ตามแอปพลิเคชันเซิร์ฟเวอร์ในปัจจุบัน (สร้างขึ้นบ่อย ๆ บนเฟรมเวิร์ก bloaty ;-)) ต้องการฮีปที่เกิน 4Gb ได้อย่างง่ายดาย

ทางออกหนึ่งสำหรับความต้องการหน่วยความจำเหล่านี้คือการ 'ถ่ายข้อมูล' ส่วนของวัตถุไปยังฮีปที่ไม่ใช่จาวา (จัดสรรโดยตรงจากระบบปฏิบัติการ) โชคดีที่ java.nio จัดเตรียมคลาสเพื่อจัดสรร / อ่านและเขียนหน่วยความจำ 'ที่ไม่มีการจัดการ' โดยตรง (แม้แต่ไฟล์ที่แม็พหน่วยความจำ)

ดังนั้นหนึ่งสามารถจัดสรรหน่วยความจำ 'ไม่ได้จัดการ' จำนวนมากและใช้สิ่งนี้เพื่อบันทึกวัตถุที่นั่น เพื่อบันทึกวัตถุโดยพลการลงในหน่วยความจำที่ไม่มีการจัดการทางออกที่ทำงานได้มากที่สุดคือการใช้อนุกรม ซึ่งหมายความว่าแอปพลิเคชันจะทำให้วัตถุเป็นอนุกรมในหน่วยความจำ offheap ในภายหลังบนวัตถุสามารถอ่านได้โดยใช้

ขนาดฮีพที่จัดการโดย java VM สามารถเก็บไว้เล็กดังนั้น GC หยุดชั่วคราวอยู่ในมิลลิวินาทีทุกคนมีความสุขทำงานเสร็จแล้ว

เป็นที่ชัดเจนว่าประสิทธิภาพของบัฟเฟอร์ฮีปปิดนั้นขึ้นอยู่กับประสิทธิภาพของการใช้การทำให้เป็นอนุกรม ข่าวดี: ด้วยเหตุผลบางอย่าง FST-serialization ค่อนข้างเร็ว :-)

สถานการณ์การใช้งานตัวอย่าง:

  • แคชเซสชันในแอปพลิเคชันเซิร์ฟเวอร์ ใช้ไฟล์ที่แมปหน่วยความจำเพื่อจัดเก็บกิกะไบต์ของเซสชันผู้ใช้ (ไม่ได้ใช้งาน) เมื่อผู้ใช้ลงชื่อเข้าใช้แอปพลิเคชันของคุณคุณสามารถเข้าถึงข้อมูลที่เกี่ยวข้องกับผู้ใช้ได้อย่างรวดเร็วโดยไม่ต้องจัดการกับฐานข้อมูล
  • การแคชผลลัพธ์การคำนวณ (เคียวรี, เพจ html, .. ) (ใช้ได้เฉพาะในกรณีที่การคำนวณช้ากว่าดีซีเรียลไลซ์วัตถุผลลัพธ์ ofc)
  • ง่ายมากและรวดเร็วคงทนโดยใช้ไฟล์หน่วยความจำแม

แก้ไข: สำหรับบางสถานการณ์หนึ่งอาจเลือกอัลกอริทึม Garbage Collection ที่ซับซ้อนยิ่งขึ้นเช่น ConcurrentMarkAndSweep หรือ G1 เพื่อสนับสนุนฮีปที่ใหญ่ขึ้น (แต่นี่ยังมีข้อ จำกัด เกินกว่าฮีป 16GB) นอกจากนี้ยังมี JVM เชิงพาณิชย์พร้อม GC แบบ 'หยุดชั่วคราว' ที่ได้รับการปรับปรุงให้ดีขึ้น


4
"จัดสรรหน่วยความจำ 'ที่ไม่มีการจัดการ' จำนวนมากและใช้สิ่งนี้เพื่อบันทึกวัตถุที่นั่น" - คุณไม่สามารถบันทึกออบเจ็กต์ offheap คุณสามารถจัดเก็บแบบพื้นฐานคุณสามารถรวมมันไว้ในไลบรารีใดก็ได้ที่คุณต้องการ แต่สิ่งเหล่านี้ไม่ใช่วัตถุ ข้อมูลที่คุณวาง offheap ไม่มีส่วนหัวของวัตถุคุณไม่สามารถซิงโครไนซ์ได้คุณไม่สามารถอ้างถึงด้วยเขตข้อมูลอ้างอิงในวัตถุอื่น
Nitsan Wakart

41

ฮีปคือสถานที่ในหน่วยความจำที่มีการจัดสรรออบเจ็กต์แบบไดนามิกของคุณ ถ้าคุณใช้newแล้วมันอยู่ในกอง ซึ่งตรงกันข้ามกับพื้นที่สแต็คซึ่งเป็นที่ที่สแต็กของฟังก์ชันมีชีวิต หากคุณมีตัวแปรโลคัลการอ้างอิงนั้นอยู่บนสแต็ก กองของ Java นั้นขึ้นอยู่กับการรวบรวมขยะและวัตถุนั้นสามารถใช้งานได้โดยตรง

ที่เก็บข้อมูลนอกฮีปของ EHCache จะลบวัตถุปกติของคุณออกจากฮีปทำให้เป็นอนุกรมและจัดเก็บเป็นไบต์ในหน่วยความจำจำนวนหนึ่งที่ EHCache จัดการ มันเหมือนเก็บไว้ในดิสก์ แต่ยังอยู่ใน RAM วัตถุไม่สามารถใช้งานได้โดยตรงในสถานะนี้พวกเขาจะต้องทำการดีซีเรียลไลซ์ก่อน ยังไม่ได้รับการเก็บขยะ


ไม่ใช่เพียงแค่อยู่ในกอง แต่เป็นรูปแบบต่อเนื่องหรือไม่
Pacerier

1
มันทำให้มีประสิทธิภาพมากขึ้นได้อย่างไร?
Pacerier

2
มีหลายวิธี เนื่องจากอ็อบเจ็กต์ไม่ได้อยู่บนฮีปหลักของ Java อีกต่อไปพวกเขาจะไม่เสียเวลาในการเก็บขยะพวกเขาจึงไม่แยกส่วนฮีปของ JVM และพวกเขาจะเพิ่มพื้นที่ว่างสำหรับวัตถุที่ใช้อื่น ๆ นอกจากนี้เนื่องจากพวกเขากำลังต่อเนื่องและไม่น่าจะมีความจำเป็นในอนาคตอันใกล้พวกเขาสามารถบีบอัดย้ายตามความจำเป็นหรือแม้แต่เพจออกไปยังดิสก์
อดัม

1
ใน Hotspot เวลาหยุด GC ขึ้นอยู่กับขนาดฮีปโดยตรง BigMemory นำเสนอการแลกเปลี่ยนนี้โดยใช้ RAM แทนการฮีปเพื่อให้ GC หยุดชั่วคราวให้น้อยที่สุดและหลีกเลี่ยงค่าใช้จ่ายในการเข้าถึงดิสก์ IO
Chander Shivdasani

17

ในภาพย่อ

ที่เก็บข้อมูล Java On / Off Heap ในระยะสั้น

เครดิตรูป


ภาพรายละเอียด

ที่เก็บข้อมูล Java On / Off Heap โดยละเอียด

เครดิตรูป


หน่วยความจำฮีปควบคุมโดย -xmx หรือไม่ สีน้ำเงินอันเก่าแก่หรือเปล่า
Himanshu Ahire

ไม่มันเป็นพื้นที่ที่ไม่ได้ใช้ในฮีปมันจะถูกเติมเมื่อมีวัตถุจำนวนมากที่สร้างในฮีป
mrsrinivas

1

JVM ไม่รู้อะไรเลยเกี่ยวกับหน่วยความจำแบบ off-heap Ehcache ใช้แคชบนดิสก์เช่นเดียวกับแคชในหน่วยความจำ


1

ไม่ใช่ 100%; อย่างไรก็ตามดูเหมือนว่า heap เป็นวัตถุหรือชุดของพื้นที่ที่จัดสรร (บน RAM) ที่สร้างไว้ในฟังก์ชันการทำงานของโค้ดไม่ว่าจะเป็น Java เองหรือการทำงานที่เป็นไปได้มากขึ้นจาก ehcache และ off-heap Ram มีระบบของตัวเองเป็น ดี; แม้กระนั้นดูเหมือนว่านี่จะมีขนาดที่ช้ากว่าเพราะมันไม่ได้มีการจัดระเบียบหมายความว่ามันอาจไม่ใช้ฮีป (หมายถึงพื้นที่หน่วยความจำยาวหนึ่งชุด) และใช้พื้นที่แอดเดรสที่ต่างกันแทนซึ่งทำให้มีประสิทธิภาพน้อยลงเล็กน้อย

แน่นอนว่าระดับที่ต่ำกว่าถัดไปคือพื้นที่ฮาร์ดไดรฟ์

ฉันไม่ได้ใช้ ehcache ดังนั้นคุณอาจไม่อยากเชื่อใจฉัน แต่นั่นคือสิ่งที่ฉันรวบรวมจากเอกสารของพวกเขา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.