สิ่งที่ JVM ต้องการในการโหลดคือสตรีมไบนารีซึ่งสามารถอยู่ในรูปแบบของไฟล์. class หรือรูปแบบอื่น ๆ หากคุณออกแบบตามมาตรฐานการโหลดจะไม่มีปัญหาใหญ่
ต่อไปนี้วิเคราะห์สองประเด็นของกลไกและมาตรฐาน:
ก่อนอื่นให้ใช้กลไกการโหลดของไฟล์คลาส Java ซึ่งคล้ายกับกลไกการโหลดของตัวแปร มันจะโหลดไฟล์คลาสลงในหน่วยความจำก่อนจากนั้นตรวจสอบวิเคราะห์และเริ่มต้นข้อมูลและในที่สุดก็สร้างประเภท Java ที่เครื่องเสมือนสามารถใช้โดยตรง เนื่องจาก Java ใช้กลไก JIT มันจะช้าในการโหลด แต่ข้อดีของมันชัดเจนมันมีความยืดหยุ่นสูงและรองรับการโหลดแบบไดนามิกและการเชื่อมต่อแบบไดนามิก
ถัดไปพูดคุยเกี่ยวกับกระบวนการโหลดของชั้นเรียน:
กระบวนการพื้นฐานของการโหลดในชั้นเรียนอยู่ในลำดับต่อไปนี้ แต่บางส่วนไม่ได้อยู่ในลำดับนี้อย่างเคร่งครัดและบางส่วนอยู่ในลำดับที่ไม่เป็นระเบียบ ตัวอย่างเช่นการโหลดแบบไดนามิกต้องใช้การเริ่มต้นแล้วแยกวิเคราะห์
1. การโหลด
มันขึ้นอยู่กับเครื่องเสมือนในการตัดสินใจ แต่ก็มีกรณีที่เฟสข้างต้นดำเนินการเนื่องจากขั้นตอนต่อไปนี้จะถูกดำเนินการ
ในเวลานี้เครื่องเสมือนทำสามสิ่ง:
ขั้นแรกให้อ่านกระแสไบนารีของไฟล์ผ่านชื่อที่ผ่านการรับรองอย่างสมบูรณ์
ประการที่สองใส่วิธีการคงที่และตัวแปรในไฟล์ลงในพื้นที่วิธีการ
ประการที่สามสร้างวัตถุและวางไว้ในกองเป็นพอร์ทัลการเข้าถึง
โปรดทราบว่าอันแรกคือการอ่านสตรีมไบนารีและไม่ได้บอกว่าไฟล์ใดที่อ่านจากหรือที่ไหนอ่านจาก ดังนั้นจึงสร้างความสามารถในการปรับขนาดที่แข็งแกร่งใน Java ซึ่งอาจมาจาก Jar, Zip หรือจากเลเยอร์เครือข่ายชั้นฐานข้อมูล ฯลฯ
ส่วนใหญ่การประกาศพื้นที่วัตถุและวิธีการ
2. การตรวจสอบ
ตรวจสอบให้แน่ใจว่าการไหลแบบไบนารีเป็นไปตามข้อกำหนดของเครื่องเสมือนและไม่ตรงกับ VerifyError
ก่อนอื่นการตรวจสอบรูปแบบไฟล์ไม่ว่าจะมีหมายเลขเวทย์มนตร์หรือไม่และตรงตามข้อกำหนดของไฟล์ Java หรือไม่
ประการที่สองการตรวจสอบข้อมูลเมตาไม่ว่าจะเป็นไปตามข้อกำหนดของรหัส Java เช่นคลาสนามธรรมนั้นมีการสร้างอินสแตนซ์โดยตรงไม่ว่าจะเป็นคลาสธรรมดามีวัตถุทางอ้อมหรือวัตถุระดับแม่โดยตรง ฯลฯ ; ประการที่สามการตรวจสอบ bytecode วิเคราะห์การไหลของข้อมูลและการควบคุมการไหลและทำให้มั่นใจได้ว่าจะไม่มีพฤติกรรมที่เป็นอันตรายต่อเครื่องเสมือนเช่นว่าจะเรียกคำสั่งที่ไม่มีอยู่จริงไม่ว่าจะกำหนดคลาสแม่ให้กับคลาสย่อยไม่ว่าจะกำหนดวัตถุให้กับวัตถุประเภทนี้ ฯลฯ ;
ประการที่สี่การตรวจสอบการอ้างอิงเชิงสัญลักษณ์ส่วนใหญ่คำอธิบายของคลาสตัวแปรและวิธีการสามารถพบได้เช่นว่าไฟล์สามารถพบได้ด้วยชื่อที่มีคุณสมบัติครบถ้วนไม่ว่าจะสามารถเข้าถึงได้ ฯลฯ
ส่วนใหญ่กำหนดโครงสร้างภายใน
3. เตรียม
การกำหนดค่าเริ่มต้นให้กับตัวแปรคลาสมักจะเป็นค่า 0 เช่นตัวแปรสแตติกโดยไม่ต้องกำหนดค่าให้กับตัวแปรอินสแตนซ์
4. การวิเคราะห์
กระบวนการแปลงการอ้างอิงเชิงสัญลักษณ์ในกลุ่มคงที่เป็นการอ้างอิงโดยตรง การอ้างอิงเชิงสัญลักษณ์ที่กล่าวถึงที่นี่หมายถึงประเภทตัวแปรและการอ้างอิงโดยตรงหมายถึงด้ามจับที่สามารถอยู่กับวัตถุโดยตรง คลาส, วิธี, ฟิลด์, การแยกวิเคราะห์อินเตอร์เฟส, รับวัตถุที่เกี่ยวข้องตามชื่อที่ผ่านการรับรองอย่างสมบูรณ์และรับประเภท หากไม่มีการเข้าถึงชั้นเรียนจะมีการโยน ungleclaccessError จะไม่มีการโยน nosuchfielderror ในฟิลด์จะไม่มีวิธีการที่จะโยน nosuchmethoderror หากเป็นชั้นเรียนหรือไม่อินเทอร์เฟซจะถูกโยน
5. การเริ่มต้น
โหลดคลาสและทรัพยากรที่จำเป็นตามข้อกำหนดของโปรแกรม มีเพียงสี่สถานการณ์และคุณต้องเริ่มต้นอย่างแข็งขันก่อนที่คุณจะสามารถดำเนินการต่อไปได้ดังนั้นคุณต้องดำเนินการสี่ขั้นตอนข้างต้นก่อน
ขั้นแรกคลาสที่มีคำหลักใหม่หรือแบบคงที่ใหม่สร้างวัตถุและโหลดคงที่แบบคงที่ทั้งสองนี้จะเริ่มต้นอย่างชัดเจน
ประการที่สองถ้าคุณใช้ชั้นเรียนไม่มีอะไรที่คุณสามารถทำได้เกี่ยวกับเรื่องนี้
ประการที่สามวิธีการในคลาสการสะท้อนจะต้องเริ่มต้นใช่ไหม?
ประการที่สี่คลาสหลักของการดำเนินการคลาสที่ใช้วิธีหลัก สถานการณ์การเริ่มต้นแบบพาสซีฟอื่น ๆ ไม่จำเป็นต้องพิจารณา
ตัวอย่างเล็ก ๆ :
คลาสสาธารณะ superclass {static {system.out.println ("superclass !!");} ค่า int คงที่สาธารณะ = 1;} คลาสย่อยคลาสย่อยขยาย superclass {คงที่ {system.out.println ("subclass !!");}} การทดสอบระดับสาธารณะ {system.out.println (subclass.value); superclass superclass = new subclass ();}} superclass !! 1SubClass !!ผลการดำเนินการแสดงปัญหา: เมื่อ subclass เรียกตัวแปรคลาสพาเรนต์คลาสย่อยจะไม่เริ่มต้นเนื่องจากความสัมพันธ์ของรหัสในเวลานี้ไม่มีส่วนเกี่ยวข้องกับคลาสย่อย; เมื่อ subclass เริ่มต้นคลาสพาเรนต์จะไม่เริ่มต้นอีกครั้งเนื่องจากคลาสแม่ได้รับการเริ่มต้นในตัววิธีการปัจจุบัน ความแตกต่างเพียงอย่างเดียวระหว่างอินเทอร์เฟซและคลาสพาเรนต์คือการเริ่มต้นอินเตอร์เฟสไม่จำเป็นต้องใช้อินเทอร์เฟซพาเรนต์และจะเริ่มต้นเฉพาะเมื่อมีการใช้อินเทอร์เฟซพาเรนต์และตัวสร้างคลาสเดียวกันจะถูกสร้างขึ้น
ในเวลานี้ตัวสร้างคลาสจะถูกโหลดและตัวแปรทั้งหมดในคลาสจะเริ่มต้น แน่นอนคลาสแม่จะเริ่มต้นก่อนชั้นเรียนเด็ก
6. ใช้
หลังจากโหลดวิธีเรียกมันการวาดการคำนวณ ฯลฯ
7. ถอนการติดตั้ง
ชั้นเรียนไม่ได้เรียกอีกต่อไป
ไม่ว่าสองคลาสจะเท่ากับส่วนใหญ่ขึ้นอยู่กับการโหลดครั้งแรกโดยใช้ตัวโหลดเดียวกันและที่อยู่ชื่อที่ผ่านการรับรองที่สองนั้นเหมือนกัน
ทำไมถามคำถามข้างต้น? ต่อไปเราจะพูดคุยเกี่ยวกับกลไกการโหลดของเครื่องเสมือน
จากมุมมองของเครื่องเสมือน Java มีตัวโหลดคลาสสองชั้นหนึ่งเรียกว่าตัวโหลดระบบ (bootstrap classloader) และอีกเครื่องหนึ่งเรียกว่าตัวโหลดที่กำหนดเอง (ขยายคลาสโหลด) สิ่งนี้ถูกแบ่งออกเป็นสองรายการหนึ่งเรียกว่าแอปพลิเคชันโหลดเดอร์และอีกอันเรียกว่าตัวโหลดคลาสส่วนขยายซึ่งโดยทั่วไปจะผิดนัดเป็นอดีต และการโหลดแอปพลิเคชันของเราส่วนใหญ่ทำโดยรถตักสามตัวข้างต้น ความสัมพันธ์ระหว่างทั้งสามคือแอปพลิเคชัน> ส่วนขยาย> bootsrap กลไกการมอบหมายผู้ปกครองหมายถึงการรวมกันของสองคู่ ตัวโหลดเด็กเรียกใช้วิธีการโหลดเดอร์หลักและไม่พบวัตถุเป้าหมายก่อนที่จะใช้ตัวโหลดเด็ก
รหัสหลอกมีดังนี้:
loadclass (ชื่อสตริง, การแก้ไขบูลีน) {class c = findloadedclass () ถ้า (c == null) {ถ้า (parent! = null) c = parent.loadclass (ชื่อ, เท็จ); c = findbootstrapclassornull (ชื่อ);Java สนับสนุนว่าเราเขียนตรรกะของคลาสการโทรของเราใน FindClass ซึ่งจะช่วยให้เราใช้กลไกการมอบหมายผู้ปกครองตามปกติ
ทำลาย 1. เขียน loadclass ใหม่
ทำลาย 2. ใช้ตัวโหลดบริบทของเธรดเพื่อให้ตัวโหลดหลักเรียกใช้วิธีการโหลดเด็ก
การทำลาย 3. วิธีที่ใช้กันทั่วไปสำหรับการโหลดร้อนคือการปรับแต่งคลาสโหลดเดอร์คลาสและเขียนทับโมดูลบั๊กดั้งเดิม - OSGI
อย่างไรก็ตามหากกฎระหว่างรถตักที่กำหนดเองนั้นสับสนและมีปัญหาในการอ้างอิงซึ่งกันและกันในเวลาเดียวกันในที่สุดคลาสจะไม่พบและการหยุดชะงักของเธรดและการรั่วไหลของหน่วยความจำจะเกิดขึ้น
เกี่ยวกับการซ่อมแซมร้อนหรือที่รู้จักกันในชื่อปลั๊กอินที่ได้รับความนิยมมากที่สุดคือ Hotfix, Nuwa, Droidfix, Andfix ฯลฯ เฟรมเวิร์กเหล่านี้สามารถพบได้ใน GitHub หรือที่อื่น ๆ หลักการดังกล่าวข้างต้นวิธีการมีความหลากหลายมีความครอบคลุมการเปลี่ยนเส้นทาง ฯลฯ ผ่านการกำหนดค่าการตั้งค่าการกระทำ ฯลฯ ; ในฐานะที่เป็นปลั๊กอินต้องปฏิบัติตามเงื่อนไขต่อไปนี้:
1. สามารถติดตั้งได้อย่างอิสระ แต่ไม่สามารถทำงานได้อย่างอิสระ
2. สามารถขยายความเข้ากันได้ย้อนหลังได้
3. สามารถทำงานในโปรแกรมโฮสต์เท่านั้นและสามารถปิดใช้งานหรือแทนที่ได้
ตัวอย่างคำอธิบายข้างต้นของกลไกการโหลดเครื่องเสมือนของ Java ขั้นสูงคือเนื้อหาทั้งหมดที่ฉันแบ่งปันกับคุณ ฉันหวังว่าคุณจะให้ข้อมูลอ้างอิงและฉันหวังว่าคุณจะสนับสนุน wulin.com มากขึ้น