JAVA ว่าด้วยเรื่อง Garbage Collection (GC) คืออะไร

Garbage Collection คืออะไร


JAVA นั้นพัฒนา GC มาเรื่อยๆ โดย Garbage Collection มีหน้าที่คืนหน่วยความจำ memory จาก object ที่ถูกสร้างขึ้นมาใช้งานและถูกทิ้งค้างไว้ โดยทำงานลบค่า reference ที่ link ระหว่างตัวแปร object และ value ออก และคืนเข้าสู่ Heap memory ซึ่งมีหลายประเภทให้ใช้งานดังนี้

    Serial Garbage Collector
    Parallel Garbage Collector
    Concurrent Mark Sweep (CMS) Garbage Collector
    G1 Garbage Collector

ใน JAVA8 ลงมา GC จะใช้ Parallel(PS) เป็น default ส่วนใน JAVA9 ขึ้นไป GC จะใช้ Garbage First (G1) เป็น default โดยถือเป็นตัวล่าสุด พัฒนาต่อมาจาก CMS อีกที และ CMS พัฒนาต่อยอดมาจาก Single และ Parallel อีกที โดยใน JAVA10 และ JAVA11 ก็ได้พัฒนา GC ต่อเนื่องไปอีก improve เรื่อง Stop The World Event เรื่อง Out of Memory (OOM) ต่างๆได้ดีกว่า ตัวเก่าๆ โดยหากเราพบ Error Out of Memory ให้เราลองไปดูใน code ว่ามีการเขียน new object แบบผิดๆอยู่หรือไม่

GC แบ่งการเก็บ Object เป็น 3 ช่วงอายุ

1. Young Gen ช่วงอายุเด็ก คือช่วงที่ app เริ่มสร้าง Object แบ่งออกเป็น 2 ช่วง คือ Eden (พึ่งสร้าง) กับ Survivor (แก่มาอีกหน่อย เตรียมโปรโมทไป Old Gen) ใน Survivor มันจะมี 2 pool เอาไว้ทำ mark copy algo ในจังหวะจะย้ายเข้า Old Gen

2. Old Gen ช่วงอายุแก่ เมื่ออัลกอของ GC หาความสัมพันธ์ได้ว่า Object ไหนใช้ยาว มันก็จะย้ายจาก Young Gen มาเก็บใน Old Gen ต้องรัน app ไปสักช่วงนึง ถึงจะย้ายมา

3. Permanent Gen อันนี้ไม่มีแสดงใน newrelic ถ้ามันหาความสัมพันธ์ได้ว่า มี Object ใช้ตลอดกาล

หากเราใช้ newrelic

กราฟบนสุด Heap คือผลรวมของ 3 กราฟ ข้างล่าง ที่แบ่งตามช่วงอายุ

สังเกตว่าช่วงที่เราพึ่งรัน app ตัว Old gen มันจะไม่มีข้อมูลเก็บ แต่ Eden กับ Survivor จะเก็บข้อมูลหนัก เมื่อ app ทำงานไปสักระยะนึง (อาจจะหลายวัน) Object ในช่วง Young จะมีการถูกย้ายมาอยู่ในช่วง Old ส่งผลให้กราฟมีการเปลี่ยนแปลง

โดยทั่วไปค่า MAX HEAP จะถูกกำหนดเป็น 1/6 ของ physical memory สมมติเครื่อง RAM 24GB เราจะเห็นกราฟ MAX HEAP เป็น 6GB ซึ่งเราสามารถแก้ไขได้ด้วยการใส่ option -xmx ในขณะรัน java

ส่วนค่า Commit Heap GC จะคำนวณให้ตามความเหมาะสม แต่เราสามารถทำ Aggressive Heap โดยใส่ option -XX:+AggressiveHeap ได้เพื่อให้มันจอง commit heap = max heap อันนี้ลองหาอ่านเพิ่มเติมเอานะ

ปล. หากเราใช้ JAVA8 แต่อยากใช้ G1 ให้ใส่ option -XX:+UseG1GC

Reference 1 : https://stackoverflow.com/a/54619838/2090568
Reference 2 : https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html

Related posts:

This entry was posted in java. Bookmark the permalink.