การจัดการหน่วยความจำใน Java

หน่วยความจำสแต็คคืออะไร?

Stack ใน java เป็นส่วนหนึ่งของหน่วยความจำซึ่งประกอบด้วยวิธีการ ตัวแปรท้องถิ่น และตัวแปรอ้างอิง หน่วยความจำสแต็กจะถูกอ้างอิงตามลำดับเข้าก่อนออกก่อนเสมอ ตัวแปรท้องถิ่นจะถูกสร้างขึ้นในสแต็ก

หน่วยความจำฮีปคืออะไร?

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

การจัดสรรหน่วยความจำใน Java

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

การขอ Java การจัดสรรหน่วยความจำแบ่งออกเป็นส่วนต่างๆ ดังต่อไปนี้:

  1. กอง
  2. กอง
  3. รหัส
  4. คงที่

การแบ่งหน่วยความจำนี้จำเป็นสำหรับการจัดการที่มีประสิทธิภาพ

  • การขอ รหัส ส่วนประกอบด้วยของคุณ รหัสไบต์.
  • การขอ กอง ส่วนของหน่วยความจำประกอบด้วย วิธีการ ตัวแปรท้องถิ่น และตัวแปรอ้างอิง
  • การขอ กอง ส่วนประกอบด้วย วัตถุ (อาจมีตัวแปรอ้างอิงด้วย)
  • การขอ คงที่ ส่วนประกอบด้วย ข้อมูล/วิธีการแบบคงที่.

ความแตกต่างระหว่างตัวแปรท้องถิ่นและอินสแตนซ์

ตัวแปรอินสแตนซ์ มีการประกาศ ภายในชั้นเรียนแต่ไม่อยู่ในวิธีการ

class Student{ 
int num; // num is  instance variable 
public void showData{}

ตัวแปรท้องถิ่น ถูกประกาศ ภายใน a วิธีการรวมทั้ง วิธี ข้อโต้แย้ง.

public void sum(int a){

int x = int a +  3;

// a , x are local variables;

}

ความแตกต่างระหว่างสแต็คและฮีป

คลิก Good Farm Animal Welfare Awards หากไม่สามารถเข้าถึงวิดีโอได้

มาดูตัวอย่างเพื่อให้เข้าใจเรื่องนี้ดีขึ้น ลองพิจารณาว่าเมธอดหลักของคุณที่เรียกใช้เมธอด m1

public void m1{
int x=20
}

ใน stack java เฟรมจะถูกสร้างขึ้นจากวิธี m1

Java กองและกอง

ตัวแปร X ใน m1 จะถูกสร้างขึ้นในเฟรมสำหรับ m1 ในสแต็กด้วย (ดูภาพด้านล่าง)

Java กองและกอง

วิธี m1 กำลังเรียกวิธี m2 ในสแต็กจาวา เฟรมใหม่จะถูกสร้างขึ้นสำหรับ m2 ที่ด้านบนของเฟรม m1

Java กองและกอง

Java กองและกอง

ตัวแปร b และ c จะถูกสร้างขึ้นในเฟรม m2 ในสแต็กด้วย

public void m2(int b){
boolean c;
}

Java กองและกอง

วิธีเดียวกันคือ m2 เรียกใช้เมธอด m3 อีกครั้ง เฟรม m3 จะถูกสร้างขึ้นที่ด้านบนสุดของสแต็ก (ดูภาพด้านล่าง)

Java กองและกอง

Java กองและกอง

ตอนนี้สมมติว่าเมธอด m3 ของเรากำลังสร้างออบเจ็กต์สำหรับคลาส "บัญชี" ซึ่งมีสองรายการ ตัวแปรอินสแตนซ์ int p และ int q

Account {
             Int p;
             Int q;
       }

นี่คือรหัสสำหรับวิธี m3

public void m3(){
	Account ref = new Account();
	// more code
}

คำสั่ง new Account() จะสร้างออบเจ็กต์ของบัญชีในฮีป

Java กองและกอง

ตัวแปรอ้างอิง “อ้างอิง” จะถูกสร้างขึ้นในสแต็กจาวา

Java กองและกอง

ตัวดำเนินการกำหนดค่า “=” จะสร้างตัวแปรอ้างอิงเพื่อชี้ไปยังอ็อบเจ็กต์ในฮีป

Java กองและกอง

เมื่อวิธีการดำเนินการเสร็จสิ้น กระแสการควบคุมจะย้อนกลับไปยังวิธีการที่เรียกใช้ ซึ่งในกรณีนี้คือวิธีการ m2

Java กองและกอง

สแต็กจากวิธี m3 จะถูกล้างออก

Java กองและกอง

เนื่องจากตัวแปรอ้างอิงจะไม่ชี้ไปที่ออบเจ็กต์ในฮีปอีกต่อไป จึงมีสิทธิ์สำหรับการรวบรวมขยะ

Java กองและกอง

เมื่อวิธี m2 ดำเนินการเสร็จสิ้น วิธีดังกล่าวจะถูกนำออกจากสแต็ก และตัวแปรทั้งหมดจะถูกล้าง และจะไม่สามารถใช้งานได้อีกต่อไป

เช่นเดียวกันกับวิธี m1

ในที่สุด กระแสการควบคุมจะกลับสู่จุดเริ่มต้นของโปรแกรม ซึ่งโดยปกติแล้วจะเป็นวิธีการ "หลัก"

จะเกิดอะไรขึ้นถ้า Object มีการอ้างอิงเป็นตัวแปรอินสแตนซ์

public static void main(String args[]) {
  A parent = new A(); //more code } class A{ B child = new B(); int e; //more code } class B{ int c; int d;  //more code }

ในกรณีนี้ ตัวแปรอ้างอิง "ลูก" จะถูกสร้างขึ้นในฮีป ซึ่งจะชี้ไปที่ออบเจ็กต์ของมัน คล้ายกับแผนภาพที่แสดงด้านล่าง

Java กองและกอง

Garbage Collection อยู่ในอะไร Java?

เก็บขยะใน Java เป็นกระบวนการที่โปรแกรมดำเนินการจัดการหน่วยความจำโดยอัตโนมัติ Garbage Collector(GC) ค้นหาวัตถุที่ไม่ได้ใช้และลบออกเพื่อเรียกคืนหน่วยความจำ ใน Javaการจัดสรรหน่วยความจำแบบไดนามิกของวัตถุจะทำได้โดยใช้ตัวดำเนินการใหม่ซึ่งใช้หน่วยความจำบางส่วนและหน่วยความจำจะยังคงได้รับการจัดสรรจนกว่าจะมีการอ้างอิงสำหรับการใช้วัตถุนั้น

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

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

ในภาษา C เป็นความรับผิดชอบของโปรแกรมเมอร์ในการยกเลิกการจัดสรรหน่วยความจำที่จัดสรรแบบไดนามิกโดยใช้ฟังก์ชัน free() นี่คือที่ Java นำไปสู่การจัดการหน่วยความจำ

หมายเหตุ วัตถุทั้งหมดถูกสร้างขึ้นในส่วน Heap ของหน่วยความจำ รายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้อยู่ในบทช่วยสอนถัดไป

ตัวอย่าง: เรียนรู้กลไกการเก็บขยะใน Java

ขั้นตอน 1) คัดลอกโค้ดต่อไปนี้ลงในโปรแกรมแก้ไข

class Student{
int a;
int b;
  public void setData(int c,int d){
    a=c;
    b=d;
  }
  public void showData(){
    System.out.println("Value of a = "+a);
    System.out.println("Value of b = "+b);
  }
  public static void main(String args[]){
    Student s1 = new Student();
    Student s2 = new Student();
    s1.setData(1,2);
    s2.setData(3,4);
    s1.showData();
    s2.showData();
    //Student s3;
    //s3=s2;
    //s3.showData();
    //s2=null;
    //s3.showData();
    //s3=null;
    //s3.showData();
  }
}

ขั้นตอน 2) บันทึก คอมไพล์ และรันโค้ด ดังที่แสดงในแผนภาพ จะมีการสร้างออบเจ็กต์สองตัวและตัวแปรอ้างอิงสองตัว


กลไกการเก็บขยะ

ขั้นตอน 3) ไม่แสดงความคิดเห็นบรรทัดที่ 20,21,22 บันทึก คอมไพล์ และรันโค้ด

ขั้นตอน 4) ดังที่แสดงในแผนภาพด้านล่าง ตัวแปรอ้างอิงสองตัวกำลังชี้ไปที่วัตถุเดียวกัน

กลไกการเก็บขยะ

ขั้นตอน 5) บรรทัดที่ไม่ใส่เครื่องหมายข้อคิดเห็น # 23 และ 24 คอมไพล์ บันทึก และรันโค้ด

ขั้นตอน 6) ดังที่แสดงในแผนภาพด้านล่าง s2 กลายเป็นโมฆะ แต่ s3 ยังคงชี้ไปที่อ็อบเจ็กต์ และไม่มีสิทธิ์สำหรับการรวบรวมขยะ Java

กลไกการเก็บขยะ

ขั้นตอน 7) บรรทัดที่ไม่ใส่เครื่องหมายข้อคิดเห็น # 25 และ 26 บันทึก คอมไพล์ และรันโค้ด

ขั้นตอน 8) ณ จุดนี้ ไม่มีการอ้างอิงที่ชี้ไปที่ออบเจ็กต์ และมีสิทธิ์สำหรับการรวบรวมขยะ มันจะถูกลบออกจากหน่วยความจำ และไม่มีทางที่จะเรียกคืนมันกลับมาได้

เรียนรู้การเก็บขยะ

วิธีการลบวัตถุใน Java?

1) หากคุณต้องการทำให้ออบเจ็กต์ของคุณมีสิทธิ์สำหรับ Garbage Collection ให้กำหนดตัวแปรอ้างอิงเป็น null

2) ประเภทดั้งเดิมไม่ใช่วัตถุ ไม่สามารถกำหนดให้เป็นโมฆะได้

วิธีการลบวัตถุใน Java

สรุป:

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