รายละเอียด Java JVM:
ความรู้ที่เกี่ยวข้องเกี่ยวกับ JVM
1. หน่วยความจำกองและสแต็ก
1. หน่วยความจำสแต็กใน JVM ส่วนใหญ่จัดเก็บการอ้างอิงถึงประเภทพื้นฐานของตัวแปรและวัตถุ
2. หน่วยความจำฮีปใน JVM ส่วนใหญ่เก็บวัตถุและอาร์เรย์ที่สร้างขึ้นด้วยสตริงใหม่และความยาวตัวแปร (StringBuilder และ StringBuffered) จะถูกเก็บไว้ในหน่วยความจำ HEAP
ข้อได้เปรียบของการใช้ฮีปคือพื้นที่จัดเก็บที่จัดสรรแบบไดนามิกซึ่งมีความยืดหยุ่นมากขึ้น แต่ข้อเสียคือมันช้ากว่าที่จะจัดสรรหน่วยความจำแบบไดนามิก ในขณะที่การใช้สแต็กนั้นเร็วขึ้นและการแบ่งปันข้อมูลสามารถทำได้ แต่ข้อเสียคือขนาดของข้อมูลและอายุการใช้งานในสแต็กจะต้องถูกกำหนดและขาดความยืดหยุ่น
3. การจัดสรรที่เก็บข้อมูลแบบคงที่ใช้เพื่อจัดเก็บตัวแปรคงที่และบล็อกรหัสคงที่
2. ความเข้าใจของ JVM
JVM เป็นเครื่องเสมือน Java มันบล็อกข้อมูลที่เกี่ยวข้องกับแพลตฟอร์มระบบปฏิบัติการเฉพาะเพื่อให้โปรแกรม Java สร้างเฉพาะรหัสวัตถุ (รหัสไบต์) ที่ทำงานบนเครื่องเสมือน Java เพื่อให้สามารถดำเนินการข้ามแพลตฟอร์มได้
หลักการของมันคือ: ไฟล์ต้นฉบับ Java ถูกรวบรวมลงในโปรแกรม bytecode ผ่านคอมไพเลอร์ Java และแต่ละคำสั่งจะถูกแปลเป็นรหัสเครื่องของแพลตฟอร์มที่แตกต่างกันผ่าน JVM และเรียกใช้ผ่านแพลตฟอร์มเฉพาะ
พื้นที่หน่วยความจำของ JVM ส่วนใหญ่แบ่งออกเป็น: พื้นที่วิธีการ, JVM สแต็ก, heap, stack วิธีการท้องถิ่น, เคาน์เตอร์โปรแกรม
ตัวนับโปรแกรม: ใช้เพื่อบันทึกคำสั่งที่ดำเนินการในปัจจุบันซึ่งเป็นพื้นที่เดียวที่ไม่มี oom;
JVM Stack: เธรดเป็นส่วนตัว แต่ละเธรดจะสร้างสแต็ก JVM ในเวลาเดียวกัน มันเก็บตัวแปรพื้นฐานท้องถิ่นในเธรดปัจจุบันผลลัพธ์การส่งคืนบางส่วนเฟรมสแต็กและที่อยู่อ้างอิงวัตถุ
HEAP: การแชร์เธรดใช้เพื่อจัดเก็บวัตถุและอาร์เรย์บางอย่าง เนื่องจากมีการแบ่งปันจึงจำเป็นต้องมีการล็อคซึ่งนำไปสู่ค่าใช้จ่ายสูง
พื้นที่วิธีการ: พื้นที่วิธีนี้สอดคล้องกับการสร้างแบบถาวรซึ่งเก็บข้อมูลของคลาส (ชื่อตัวดัดแปลง ฯลฯ ) ตัวแปรคงที่ในชั้นเรียนค่าคงที่ที่กำหนดไว้ในชั้นเรียนที่มีขั้นสุดท้าย ฯลฯ ;
สแต็กวิธีการท้องถิ่น: ใช้เพื่อสนับสนุนการดำเนินการของวิธีการดั้งเดิมและเพื่อจัดเก็บสถานะการโทรของแต่ละวิธีดั้งเดิม
คอลเลกชันขยะ Java ส่วนใหญ่มุ่งเน้นไปที่กองและพื้นที่วิธีการ: กองถูกแบ่งออกเป็นคนรุ่นใหม่และรุ่นเก่าและโดยทั่วไปวัตถุที่เพิ่งได้รับใหม่จะถูกวางลงในรุ่นใหม่; และคนรุ่นใหม่จะถูกแบ่งออกเป็นพื้นที่อีเด็นและสองพื้นที่ผู้รอดชีวิต
กลไกของการรวบรวมขยะคือ: ก่อนอื่นกำหนดว่าวัตถุใดเป็นขยะนั่นคือพวกมันไม่ได้ใช้อีกต่อไปแล้วใช้อัลกอริทึมที่สอดคล้องกัน (อัลกอริทึมการล้างเครื่องหมายอัลกอริทึมการคัดลอกอัลกอริทึมการทำเครื่องหมาย
1. อัลกอริทึมการล้างเครื่องหมาย:
มันถูกแบ่งออกเป็นสองขั้นตอนขั้นตอนการทำเครื่องหมายและขั้นตอนการล้าง ก่อนอื่นทำเครื่องหมายวัตถุที่ต้องรีไซเคิลแล้วรีไซเคิลพื้นที่ที่ถูกครอบครองโดยวัตถุที่ทำเครื่องหมาย;
การใช้งานนั้นค่อนข้างง่าย แต่ข้อเสียของมันคือมันง่ายที่จะสร้างชิ้นส่วนหน่วยความจำส่งผลให้ไม่สามารถหาหน่วยความจำที่เพียงพอเมื่อจัดสรรพื้นที่สำหรับวัตถุขนาดใหญ่ในอนาคตและกระตุ้นการดำเนินการรวบรวมขยะใหม่ล่วงหน้า
2. อัลกอริทึมคัดลอก:
เพื่อที่จะแก้ข้อบกพร่องของอัลกอริทึมการทำความสะอาดมาร์คอัลกอริทึมการคัดลอกแบ่งหน่วยความจำออกเป็นสองพื้นที่ที่มีขนาดเท่ากันตามความจุและมีเพียงหนึ่งในนั้นเท่านั้น หลังจากใช้งานชิ้นหนึ่งวัตถุที่ยังคงสืบทอดจะถูกคัดลอกไปยังพื้นที่อื่นและจากนั้นพื้นที่ที่ใช้แล้วจะถูกทำความสะอาดเพื่อให้การกระจายตัวไม่ใช่เรื่องง่ายที่จะเกิดขึ้น
ปัญหาของการกระจายตัวของหน่วยความจำได้รับการแก้ไข แต่ข้อเสียคือหน่วยความจำที่ใช้จะลดลงเหลือครึ่งหนึ่งของต้นฉบับและประสิทธิภาพการคัดลอกนั้นเกี่ยวข้องกับจำนวนวัตถุที่รอดชีวิต เมื่อจำนวนมีขนาดใหญ่ประสิทธิภาพจะลดลงอย่างมาก
3. อัลกอริทึมการทำเครื่องหมาย-องค์กร
เพื่อที่จะแก้ข้อบกพร่องของอัลกอริทึมสำเนาอัลกอริทึมมาร์คไทดีเกิดขึ้นและขั้นตอนการทำเครื่องหมายก็เหมือนอัลกอริทึมการทำความสะอาดมาร์ค ก่อนอื่นวัตถุที่ต้องรีไซเคิลจะถูกทำเครื่องหมายออก แต่มันไม่ได้รีไซเคิลโดยตรง แต่ย้ายวัตถุที่รอดชีวิตทั้งหมดไปอีกด้านหนึ่งแล้วทำความสะอาดหน่วยความจำนอกขอบเขต
4. อัลกอริทึมการรวบรวม Generational
นี่คืออัลกอริทึมที่ใช้กันมากที่สุดในปัจจุบัน แนวคิดหลักของมันคือการแบ่งหน่วยความจำออกเป็นหลายพื้นที่ตามวัฏจักรการเอาชีวิตรอดของวัตถุ โดยทั่วไปพื้นที่กองจะถูกแบ่งออกเป็นคนรุ่นใหม่และรุ่นเก่า ลักษณะของรุ่นเก่าคือมีวัตถุน้อยกว่าที่ต้องรีไซเคิลทุกครั้งที่เก็บขยะในขณะที่มีคนรุ่นใหม่มากขึ้นดังนั้นอัลกอริทึมที่แตกต่างกันจึงถูกนำมาใช้
ในปัจจุบันส่วนใหญ่ใช้อัลกอริทึมการคัดลอกรุ่นใหม่ แต่อันที่จริงคนรุ่นใหม่ไม่ได้แบ่งออกเป็นอัตราส่วน 1: 1 โดยทั่วไปแล้วคนรุ่นใหม่จะแบ่งออกเป็นพื้นที่อีเด็นขนาดใหญ่และพื้นที่ผู้รอดชีวิตขนาดเล็กสองแห่ง ทุกครั้งที่มีการใช้พื้นที่ Eden และหนึ่งในช่องว่างผู้รอดชีวิตเมื่อรีไซเคิลวัตถุที่ยังคงรอดชีวิตใน Eden และ Survivor จะถูกคัดลอกไปยังพื้นที่ผู้รอดชีวิตอีกแห่งหนึ่งจากนั้น Eden และ Spaces ผู้รอดชีวิตที่เพิ่งใช้ถูกทำความสะอาด
เนื่องจากวัยชราคือมีเพียงวัตถุจำนวนน้อยเท่านั้นที่ถูกนำกลับมาใช้ใหม่ทุกครั้งจึงใช้อัลกอริทึมที่มีขนาดกะทัดรัด
โปรดทราบว่ามีรุ่นอื่นนอกพื้นที่ฮีปซึ่งเป็นการสร้างแบบถาวรซึ่งใช้ในการจัดเก็บคลาสคลาสค่าคงที่คำอธิบายวิธีการ ฯลฯ การรีไซเคิลรุ่นถาวรส่วนใหญ่รีไซเคิลสองส่วน: ค่าคงที่ที่ถูกทิ้งและคลาสที่ไร้ประโยชน์
ดังนั้นเราจะกำหนดวัตถุใด "ขยะ" ได้อย่างไร?
วิธี 1. วิธีการนับอ้างอิง:
ใน Java มันเกี่ยวข้องกับวัตถุผ่านการอ้างอิงนั่นคือถ้าคุณต้องการใช้งานวัตถุจะต้องทำผ่านการอ้างอิง จากนั้นก็เห็นได้ชัดว่าวิธีง่ายๆคือการตัดสินว่าวัตถุสามารถรีไซเคิลได้โดยการนับการอ้างอิงหรือไม่ หากไม่มีการสูญเสียทั่วไปหากวัตถุไม่มีการอ้างอิงที่เกี่ยวข้องก็หมายความว่าวัตถุนั้นไม่น่าจะใช้ที่อื่นและจากนั้นวัตถุจะกลายเป็นวัตถุรีไซเคิล วิธีนี้กลายเป็นวิธีการนับอ้างอิง
ข้อดี: การใช้งานอย่างง่ายและประสิทธิภาพสูง
ข้อเสีย: ไม่สามารถแก้ปัญหาการอ้างอิงแบบวงกลมได้
วิธีที่ 2. วิธีการวิเคราะห์การเข้าถึง:
แนวคิดพื้นฐานของวิธีนี้คือการค้นหาผ่านชุดของวัตถุ "GC Roots" เป็นจุดเริ่มต้น หากไม่มีเส้นทางที่สามารถเข้าถึงได้ระหว่าง "ราก GC" และวัตถุวัตถุนั้นจะถูกกล่าวว่าไม่สามารถเข้าถึงได้ อย่างไรก็ตามควรสังเกตว่าวัตถุที่ตัดสินว่าไม่สามารถเข้าถึงได้อาจไม่จำเป็นต้องกลายเป็นวัตถุที่รีไซเคิลได้ วัตถุที่ถูกตัดสินว่าไม่สามารถเข้าถึงได้ต้องผ่านกระบวนการทำเครื่องหมายอย่างน้อยสองกระบวนการเพื่อให้กลายเป็นวัตถุรีไซเคิลได้ หากยังไม่มีความเป็นไปได้ที่จะกลายเป็นวัตถุรีไซเคิลในระหว่างกระบวนการทำเครื่องหมายทั้งสองนี้มันจะกลายเป็นวัตถุรีไซเคิลได้
วัตถุใดที่สามารถเป็นราก GC ได้?
1. วัตถุที่อ้างอิงใน JVM สแต็ก (ตารางตัวแปรท้องถิ่นในเฟรมสแต็ก)
2. วัตถุอ้างอิงโดยแอตทริบิวต์คงที่คลาสในพื้นที่วิธีการ
3. วัตถุที่อ้างอิงโดยค่าคงที่ในพื้นที่วิธีการ
4. วัตถุที่อ้างอิงโดย JNI (นั่นคือวิธีการทั่วไปทั่วไป) ในสแต็กวิธีการท้องถิ่น
สำหรับโปรแกรมเมอร์เรายังสามารถลดค่าใช้จ่าย GC ผ่านวิธีการบางอย่าง:
1. อย่าแสดงเมธอด system.gc ()
2. ลดการใช้วัตถุชั่วคราวให้น้อยที่สุด
3. เมื่อวัตถุไม่ได้ใช้งานการตั้งค่าการแสดงผลจะถูกตั้งค่าเป็น null
4. พยายามใช้ StringBuilder แทนสตริงสะสมสตริง
5. หากคุณสามารถใช้ตัวแปรประเภทพื้นฐาน (ยาว int) อย่าใช้วัตถุ (จำนวนเต็มยาว)
6. ใช้ตัวแปรวัตถุแบบคงที่น้อยที่สุด
ขอบคุณสำหรับการอ่านฉันหวังว่ามันจะช่วยคุณได้ ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!