JVM Config

java heap memory หลายคนที่พัฒนาโปรแกรมด้วยภาษา java คงเคยเจอ การจัดสรรทรัพยากรที่ไม่ได้ประสิทธิภาพ แล้วต้องทำไงละถึงจะใช้ได้คุ้มค่า และตอบสนองได้สูงสุด เพื่อให้เข้าใจการทำงานของ jvm วันนี้จะพามาดูถึง jvm ควร config ค่ายังไง เพื่อให้ระบบทำงานได้เต็มประสิทธิภาพ


ตัวอย่างค่า Config JVM จาก RAM 64GB และการทำงานของ JVM

jvmargs {
       maxMetaspace=[
            "-XX:MaxMetaspaceSize=16384M"
        ]
        xms=[
            "-Xms16384M"
        ]
        xmx=[
            "-Xmx49152M"
        ]
        gc=[
            "-XX:+UseConcMarkSweepGC",
            "-XX:+CMSIncrementalMode"
        ]
}

จากค่าตัวอย่างจะเห็นว่าการใช้ xmx จะใช้ได้ประมาณ 75% ของ RAM ทั้งหมด 64 GB

คำถามแล้วที่เหลือไปไหนละ ? เอาไว้ให้ system running ใช้ไง เช่น OS


อธิบายเพิ่มเติม

MaxMetaspaceSize เป็นตัวกำหนดค่าการจองเนื้อที่ในหน่วยความจำสำหรับ Metaspace ใน Java Virtual Machine (JVM)


Metaspace เป็นพื้นที่ที่ JVM ใช้เพื่อจัดเก็บข้อมูลการนำเข้าคลาส (class metadata) ที่ต้องการสำหรับการทำงานของโปรแกรม Java. มันมีประโยชน์ในการควบคุมจำนวนคลาสที่สามารถถูกโหลดได้ใน JVM และสามารถช่วยป้องกันการใช้งานความจำแบบไม่อั้นเนื่องจากการโหลดคลาสเกินจำนวน


ในตัวอย่างเราใช้, MaxMetaspaceSize=16384M หมายความว่า JVM จะจองเนื้อที่ในหน่วยความจำสูงสุด 16,384 megabytes (หรือ 16 gigabytes) สำหรับ Metaspace. หาก Metaspace ต้องการเพิ่มขนาดอีกและถึงขีดจำกัดนี้, JVM จะทำการเก็บกวาด (Garbage Collect) เพื่อพยายามปล่อยพื้นที่. ถ้าก็ยังไม่พอ, JVM จะส่งข้อผิดพลาด OutOfMemoryError


โปรดทราบว่า Metaspace ใน Java 8 และเวอร์ชันถัดไปแทนที่คลาส Permanent Generation (PermGen) ที่ใช้ใน Java 7 และเวอร์ชันก่อนหน้า


-Xms และ -Xmx เป็นตัวเลือกการกำหนดค่าความจำสำหรับ Java Virtual Machine (JVM). ในคำสั่งรัน Java, คุณสามารถใช้พารามิเตอร์เหล่านี้เพื่อกำหนดขนาดของ heap memory ที่จะใช้งาน


  • -Xms: ตัวเลือกนี้กำหนดขนาดเริ่มต้นของ heap memory ที่ JVM จะใช้งาน. ในตัวอย่างของคุณ, คำสั่ง -Xms16384M หมายความว่า heap จะเริ่มที่ขนาด 16384 megabytes หรือประมาณ 16 gigabytes.
  • -Xmx: ตัวเลือกนี้กำหนดขนาดสูงสุดของ heap memory ที่ JVM สามารถใช้งานได้. ในตัวอย่างของคุณ, คำสั่ง -Xmx49152M หมายความว่า heap สามารถขยายขึ้นไปสูงสุด 49152 megabytes หรือประมาณ 48 gigabytes


Heap memory ใช้สำหรับการจัดเก็บข้อมูลวัตถุและสิ่งที่สร้างขึ้นด้วยคำสั่ง new ในภาษา Java. ขนาดของ heap สามารถขยายและลดลงได้ในระหว่างการทำงานของโปรแกรม, แต่จะไม่เกินขนาดที่กำหนดด้วย -Xmx. ถ้า heap memory เต็ม และไม่สามารถขยายได้เพิ่ม, JVM จะส่งข้อผิดพลาด OutOfMemoryError


การตั้งค่า -Xms และ -Xmx มีผลต่อประสิทธิภาพของโปรแกรม Java. หากขนาด heap ต่ำเกินไป, จะทำให้มีการเก็บกวาดความจำ (garbage collection) เกิดขึ้นบ่อยเกินควร ทำให้ประสิทธิภาพลดลง. แต่หากขนาด heap สูงเกินไป, การเก็บกวาดความจำจะใช้เวลานาน, และอาจทำให้โปรแกรมหยุดการทำงานชั่วขณะ. ดังนั้น, การตั้งค่าเหล่านี้ต้องคำนึงถึงสมดุลระหว่างใช้งานความจำและประสิทธิภาพ



เข้าเนื้อหาสำคัญ

หลังจากที่เราได้รู้การทำงานของ JVM ไปแล้ว ก็อาจจะสงสัยว่าเราสามารถปรับแต่ง JVM ในขณะทำงานได้ไหม ซึ่ง JVM ก็มี option ที่เป็น Standard Options, Non-standard Options และ Advance Option ให้สำหรับปรับแต่งการทำงานดังนี้



Standard Options

เราสามารถใช้คำสั่ง java เพื่อแสดงรายการ option มาตรฐานของ JVM สามารถเลือกใช้งานได้ตามที่ต้องการ โดยที่ option สำคัญดังนี้


-Dproperty=value

เป็นการตั้งค่า property ของระบบ ตัวแปร property เป็น String ที่ไม่มีช่องว่างหลังจาก -D (Define) แทนที่ชื่อของ property และตัวแปร value เป็น String แทนทีค่าของ property ถ้ามีช่องว่างระหว่างคำจะต้องมีเครื่องหมาย “” กำกับ (ตัวอย่างเช่น -Dfoo="foo bar")


-server

เป็นการเลือก Hotspot Server VM ซึ่ง JDK เวอร์ชัน 64bit เท่านั้นที่รองรับ option นี้


-client

เป็นการเลือก Hotspot Client VM ถ้าเป็น JDK เวอร์ชัน 64bit จะไม่รองรับ option นี้ แต่ใช้ Hotspot Server VM แทน


-d32/-d64

เป็นการระบุว่าจะให้ JVM ทำงานในโหมด 32bit หรือ 64Bit แต่โดยค่าเริ่มต้นจะรันแอพพลิเคชันในโหมด 32bit เว้นแต่ระบบ 64bit ถูกใช้งาน ตอนนี้มีเพียง Hotspot VM ที่รองรับ 64bit และถ้าใช้ option -server จะใช้งาน -d64 โดยปริยาย แต่ถ้าใช้ -client จะไม่ใช้งาน -d64



Non-Standard Options

เราสามารถใช้คำสั่ง java -X เพื่อแสดงรายการของ option เฉพาะของ JVM นั้นๆ และ option ที่สำคัญดังนี้


-Xint

เป็นการรันแอพพลิเคชันในโหมด interpreted-only ซึ่งการใช้งาน native code จะถูกปิดการใช้งาน และ bytecode จะถูกประมวลผลด้วย interpreter การใช้งาน JIT เพื่อเพิ่มประสิทธิภาพการประมวลผลจะไม่เห็นผลในโหมดนี้


-Xbootclasspath:path

เป็นการระบุรายการของ directory ที่มีไฟล์ JAR และ ZIP โดยแยกด้วย : เพื่อหาไฟล์คลาส boot loader


-Xloggc:filename

เป็นระบุไฟล์ซึ่งเก็บข้อมูลของ verbose GC event สำหรับ logging โดยที่ข้อมูลจะถูกเขียนไปในไฟล์เหมือนกับที่แสดงใน output ของ -verbose:gc ซึ่ง -Xloggc จะแทนที่ -verbose:gc ถ้าใส่มาในคำสั่งชุดเดียวกัน


-Xmssize

เป็นการระบุค่าเริ่มต้นของขนาดของ Heap (หน่วยเป็น byte) เป็นค่าผลคูลของ 1024 และมากกว่า 1 MB ต่อท้ายด้วยตัวอักษรที่บ่งบอกว่าเป็นหน่วย, k หรือ K เป็นหน่วย kilobyte, m หรือ M เป็นหน่วย megabyte, g หรือ G เป็นหน่วย gigabyte ตัวอย่างต่อไปนี้เป็นการระบุค่า 6 MB


-Xms6291456
-Xms6144k
-Xms6m

ถ้าไม่ระบุ option นี้ขนาดเริ่มต้นของ Heap จะเป็นค่าของผลรวมของขนาดที่ allocate สำหรับ old generation และ young generation, -Xms


-Xmxsize

เป็นการระบุค่ามากที่สุดของขนาดของ Heap (หน่วยเป็น byte) ป็นค่าผลคูลของ 1024 และมากกว่า 2 MB ต่อท้ายด้วยตัวอักษรที่บ่งบอกว่าเป็นหน่วย, k หรือ K เป็นหน่วย kilobyte, m หรือ M เป็นหน่วย megabyte, g หรือ G เป็นหน่วย gigabyte ตัวอย่างต่อไปนี้เป็นการระบุค่า 80 MB


-Xmx83886080
-Xmx81920k
-Xmx80m

โดยเริ่มต้นจะใช้ค่าที่ถูกเลือกในขณะ runtime ซึ่งเป็นค่าของ system configuration


-Xnoclassgc

เป็นการปิดการทำงานของ Garbage Collection ของคลาส สามารถประหยัดเวลาขอ GC บ้าง ซึ่งทำให้ interrupt สั้นลงในขณะทำงานของแอพพลิเคชัน



Advance Options

นอกจาก Standard Option และ Non-Standard Option แล้วก็ยังมี option อื่นๆ อีกที่เป็นระดับสูง ซึ่งแบบได้ดังนี้


Behavior

-XX:+UseConcMarkSweepGC

สำหรับเปิดใช้งาน CMS Garbage Collection


-XX:+UseParallelGC

สำหรับเปิดใช้งาน Parallel Garbage Collection


-XX:+UseSerialGC

สำหรับเปิดใช้งาน Serial Garbage Collection


-XX:+UseG1GC

สำหรับเปิดใช้งาน G1 Garbage Collection



Performance

-XX:MaxPermSize=size

เป็นการระบุขนาดสูงสุดของ permanent generation space (หน่วยเป็น byte)


-XX:ThreadStackSize=size

เป็นการระบุขนาดของ thread stack (หน่วยเป็น byte)


-XX:+UseStringCache

เปิดใช้งานการ caching ของ commonly allocated strings


-XX:G1HeapRegionSize=size

เป็นการระบุขนาดของ sub-division ของ G1 Heap (หน่วยเป็น byte)


-XX:MaxGCPauseMillis=time

เป็นการระบุเวลานานที่สุดของการหยุดของ Garbage Collection


-XX:MaxNewSize=size

เป็นการระบุขนาดสูงสุดของ Heap สำหรับ young generation


-XX:+AggressiveOpts

เปิดใช้งาน aggressive performance optimization features


-XX:OnError=string

เป็นการระบุคำสั่งให้ทำงานเมื่อมี Error เกิดขึ้น



Debugging

-XX:ErrorFile=filename

เป็นการระบุ path และชื่อไฟล์ของ Error log


-XX:+HeapDumpOnOutOfMemory

เปิดใช้งาน dump ไฟล์ของ Java Heap ไปเป็นไฟล์ใน directory ที่ทำงานอยู่


-XX:+PrintGC

เปิดใช้งานให้แสดง message ของทุกๆ Garbage Collection


-XX:+TraceClassLoading

เปิดใช้งาน tract ของคลาสที่โหลดมาแล้ว


-XX:+PrintClassHistogram

เปิดใช้งานแสดงคลาส instance histogram หลังจาก Ctrl+C


0
213