Problem
เราจะรู้ได้อย่างไรว่าโปรแกรมจาวาที่เราเขียนขึ้นนั้นมี memory leak หรือไม่ และจะตรวจสอบอย่างไร ? จะใช้โปรแกรมอะไรในการตรวจสอบ ?
Solution
วิธีง่าย ๆ ในการตรวจสอบว่าโปรแกรมที่เราเขียนนั้นมี memory leak หรือไม่ ก็ทำได้โดยการใช้โปรแกรมที่ชื่อว่า jconsole ซึ่งเป็นโปรแกรมที่มากับ JDK 1.5 jconsole เป็นโปรแกรมที่ใช้ในการ monitor หรือตรวจสอบการทำงานของโปรแกรม ณ runtime เราสามารถจะดูปริมาณ memory ที่ใช้, จำนวน class ที่โหลด, จำนวน thread ที่สร้างขึ้น ณ runtime ได้ ในรูปแบบที่เป็น graphics ทำให้เราดูค่าเหล่านี้ได้ง่ายและสะดวกมากขึ้น
การใช้งาน jconsole มีขั้นตอนดังต่อไปนี้
1. รันโปรแกรมจาวาที่เราเขียนขึ้น โดยระบุ system property com.sun.management.jmxremote เข้าไปด้วย อย่างเช่น
java -Dcom.sun.management.jmxremote -cp ... ClassName
ลอง compile และรันโปรแกรมด้านล่างนี้ ซึ่งจะใช้ memory เพิ่มขึ้นไปเรื่อย ๆ เป็นการจำลองการเกิด memory leak โดยการสร้าง int[] ขนาด 1000 ตัว แล้วเพิ่มเข้าไปใน ArrayList ทุก ๆ 1 วินาที
import java.util.*;
public class TestMemLeak { private static List objects = new ArrayList();
public static void main(String[] args) { for (int i = 0; i < 10000; i++) { try {
objects.add(new int[1000]); // เพิ่ม int[] object เข้าไปใน List ทุก ๆ 1s
System.out.println("# of objects = " + objects.size()); Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace();
}
}
}
}
รันโปรแกรมตัวอย่าง TestMemLeak ด้วยคำสั่ง
java -Dcom.sun.management.jmxremote TestMemLeak
2. รันโปรแกรม jconsole โดยเรียกใช้คำสั่ง jconsole ที่ command-prompt (โปรแกรม jconsole จะอยู่ใน JAVA_INSTALL\bin เหมือนกับ javac และ java ถ้าเรากำหนด PATH ไว้แล้วก็สามารถเรียกใช้ได้เลย)
โปรแกรม jconsole จะขึ้นมาทำงาน พร้อมกับแสดงหน้าจอ Connect to Agent เพื่อให้เราเลือก connect ไปหา agent ที่ทำงานอยู่ใน Java VM ในรูปเราจะเห็น process ของโปรแกรม TestMemLeak อยู่ ให้เราเลือก process ของโปรแกรม TestMemLeak แล้วกด connect (เราจะเห็นเฉพาะ process ของโปรแกรมจาวาที่มีการระบุ system property com.sun.management.jmxremote เอาไว้เท่านั้น)