หน้านี้อธิบายวิธีลดการใช้หน่วยความจำภายในแอปแบบเชิงรุก สำหรับข้อมูลเกี่ยวกับ วิธีที่ระบบปฏิบัติการ Android จัดการหน่วยความจำ โปรดดูที่ ภาพรวมของการจัดการหน่วยความจำ
หน่วยความจำเข้าถึงโดยสุ่ม (RAM) เป็นทรัพยากรที่มีคุณค่าสำหรับสภาพแวดล้อมการพัฒนาซอฟต์แวร์ทุกประเภท และ
จะยิ่งมีประโยชน์มากสำหรับระบบปฏิบัติการบนอุปกรณ์เคลื่อนที่ ซึ่งหน่วยความจำทางกายภาพมักจะถูกจำกัด
แม้ว่าเครื่องเสมือน Android Runtime (ART) และ Dalvik จะใช้ระบบขยะตามปกติ
แต่ไม่ได้หมายความว่าคุณจะไม่สนใจเวลาและสถานที่ที่แอปจัดสรรและเผยแพร่หน่วยความจำได้
คุณยังคงต้องหลีกเลี่ยงการรั่วไหลของหน่วยความจำ ซึ่งมักเกิดจากการถือวัตถุไว้ใกล้ตัว
อ้างอิงในตัวแปรสมาชิกแบบคงที่ และปล่อย
ออบเจ็กต์ Reference
รายการที่
เวลาที่เหมาะสมตามที่กำหนดโดย Callback ของวงจร
ตรวจสอบหน่วยความจําที่ใช้ได้และการใช้งานหน่วยความจํา
คุณต้องพบปัญหาการใช้หน่วยความจำของแอปก่อน จึงจะแก้ไขปัญหาได้ เครื่องมือสร้างโปรไฟล์หน่วยความจำใน Android Studio จะช่วยคุณค้นหา และวิเคราะห์ปัญหาเกี่ยวกับหน่วยความจำด้วยวิธีต่อไปนี้
- ดูวิธีที่แอปของคุณจัดสรรหน่วยความจำเมื่อเวลาผ่านไป เครื่องมือสร้างโปรไฟล์หน่วยความจำจะแสดงกราฟแบบเรียลไทม์แสดง หน่วยความจำที่แอปใช้อยู่ จำนวนออบเจ็กต์ Java ที่จัดสรร และเมื่อมีการเก็บข้อมูลขยะ เกิดขึ้น
- เริ่มเหตุการณ์การเก็บรวบรวมขยะและถ่ายสแนปชอตของฮีป Java ในขณะที่แอป วิ่งได้
- บันทึกการจัดสรรหน่วยความจำของแอป ตรวจสอบออบเจ็กต์ที่จัดสรรทั้งหมด ดูสแต็กเทรซสําหรับการจัดสรรแต่ละรายการ และข้ามไปยังโค้ดที่เกี่ยวข้องในตัวแก้ไข Android Studio
ปล่อยหน่วยความจำเพื่อตอบสนองต่อเหตุการณ์
Android สามารถเรียกคืนหน่วยความจำจากแอปของคุณ หรือหยุดแอปของคุณไปเลยหากจำเป็นเพื่อเพิ่มหน่วยความจำ
สำหรับงานสำคัญตามที่อธิบายไว้ใน
ภาพรวมของการจัดการหน่วยความจำ เพื่อรับความช่วยเหลือเพิ่มเติม
รักษาความสมดุลของหน่วยความจำของระบบ และหลีกเลี่ยงไม่ให้ระบบต้องหยุดกระบวนการของแอป คุณสามารถใช้
เวลา
ComponentCallbacks2
ในชั้นเรียน Activity
ของคุณ
ที่ระบุ
onTrimMemory()
เมธอด Callback จะแจ้งเตือนแอปของคุณเกี่ยวกับเหตุการณ์อายุการใช้งานหรือเหตุการณ์ที่เกี่ยวข้องกับหน่วยความจำซึ่งแสดงถึง
ที่แอปจะลดการใช้หน่วยความจำโดยสมัครใจ การปล่อยหน่วยความจำอาจลด
ความเป็นไปได้ที่แอปของคุณจะถูกฆ่า
ประสิทธิภาพหน่วยความจำต่ำ
คุณสามารถใช้ Callback onTrimMemory()
เพื่อตอบสนองต่อหน่วยความจำอื่นๆ ที่เกี่ยวข้องกับหน่วยความจำได้
เหตุการณ์ ดังที่ปรากฏในตัวอย่างต่อไปนี้
Kotlin
import android.content.ComponentCallbacks2 // Other import statements. class MainActivity : AppCompatActivity(), ComponentCallbacks2 { // Other activity code. /** * Release memory when the UI becomes hidden or when system resources become low. * @param level the memory-related event that is raised. */ override fun onTrimMemory(level: Int) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
Java
import android.content.ComponentCallbacks2; // Other import statements. public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { // Other activity code. /** * Release memory when the UI becomes hidden or when system resources become low. * @param level the memory-related event that is raised. */ public void onTrimMemory(int level) { if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // Release memory related to UI elements, such as bitmap caches. } if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { // Release memory related to background processing, such as by // closing a database connection. } } }
ตรวจสอบจำนวนหน่วยความจำที่ต้องการ
Android จะกำหนดขีดจำกัดสำหรับขนาดฮีปที่จัดสรรสำหรับแต่ละกระบวนการที่ทำงานอยู่เพื่อให้กระบวนการทำงานหลายกระบวนการได้
แอป ขีดจำกัดขนาดฮีปที่แน่นอนจะแตกต่างกันไปในอุปกรณ์แต่ละเครื่องโดยขึ้นอยู่กับจำนวน RAM ในอุปกรณ์ที่มี
โดยรวม หากแอปมีความจุฮีปเต็มและพยายามจัดสรรหน่วยความจำเพิ่มเติม ระบบจะแสดงข้อผิดพลาด
OutOfMemoryError
เพื่อป้องกันไม่ให้หน่วยความจำหมด คุณสามารถค้นหาระบบเพื่อดูจำนวนพื้นที่ฮีป
พร้อมใช้งานบนอุปกรณ์ปัจจุบัน คุณสามารถค้นหาระบบสำหรับรูปภาพนี้ได้โดยโทรไปที่
getMemoryInfo()
ซึ่งแสดงผลเป็น
ActivityManager.MemoryInfo
ที่ให้ข้อมูลเกี่ยวกับสถานะหน่วยความจำปัจจุบันของอุปกรณ์ รวมทั้ง
หน่วยความจํา หน่วยความจําทั้งหมด และเกณฑ์หน่วยความจํา ซึ่งเป็นระดับหน่วยความจําที่ระบบเริ่มทำงาน
หยุดกระบวนการ ออบเจ็กต์ ActivityManager.MemoryInfo
จะแสดงด้วย
lowMemory
,
ซึ่งเป็นบูลีนง่ายๆ ที่จะบอกคุณว่าอุปกรณ์มีหน่วยความจำเหลือน้อยหรือไม่
ตัวอย่างข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้เมธอด getMemoryInfo()
ใน
แอปของคุณ
Kotlin
fun doSomethingMemoryIntensive() { // Before doing something that requires a lot of memory, // check whether the device is in a low memory state. if (!getAvailableMemory().lowMemory) { // Do memory intensive work. } } // Get a MemoryInfo object for the device's current memory status. private fun getAvailableMemory(): ActivityManager.MemoryInfo { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager return ActivityManager.MemoryInfo().also { memoryInfo -> activityManager.getMemoryInfo(memoryInfo) } }
Java
public void doSomethingMemoryIntensive() { // Before doing something that requires a lot of memory, // check whether the device is in a low memory state. ActivityManager.MemoryInfo memoryInfo = getAvailableMemory(); if (!memoryInfo.lowMemory) { // Do memory intensive work. } } // Get a MemoryInfo object for the device's current memory status. private ActivityManager.MemoryInfo getAvailableMemory() { ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); return memoryInfo; }
ใช้โครงสร้างโค้ดที่ประหยัดหน่วยความจํามากขึ้น
ฟีเจอร์บางอย่างของ Android, คลาส Java และโครงสร้างโค้ดใช้หน่วยความจำมากกว่าฟีเจอร์อื่นๆ คุณสามารถลดปริมาณหน่วยความจำที่แอปใช้ได้โดยเลือกทางเลือกที่มีประสิทธิภาพมากขึ้นในโค้ด
ใช้บริการเท่าที่จำเป็น
เราขอแนะนำว่าอย่าปล่อยให้บริการทำงานต่อเมื่อไม่จำเป็น ปล่อยไว้โดยไม่จำเป็น บริการที่ทำงานอยู่เป็นหนึ่งในข้อผิดพลาดด้านการจัดการหน่วยความจำที่แย่ที่สุดที่แอป Android อาจเกิดขึ้นได้ หากแอปต้องใช้บริการในการทำงานในเบื้องหลัง อย่าปล่อยให้แอปทำงานอยู่จนกว่าจะต้องทำงาน หยุดบริการเมื่อทำงานเสร็จแล้ว หรือไม่เช่นนั้น อาจทำให้หน่วยความจำรั่วไหล
เมื่อคุณเริ่มต้นบริการ ระบบจะต้องการให้กระบวนการสำหรับบริการนั้นทำงานต่อไป ช่วงเวลานี้ ทำให้การประมวลผลบริการมีราคาแพงมากเนื่องจาก RAM ที่บริการใช้ยังคง ไม่สามารถใช้กับกระบวนการอื่นๆ ได้ ซึ่งจะลดจำนวนกระบวนการที่แคชไว้ซึ่งระบบสามารถ เก็บไว้ในแคช LRU ทำให้การเปลี่ยนแอปมีประสิทธิภาพน้อยลง และยังนำไปสู่การพุ่งกระชาก เมื่อมีหน่วยความจำแน่น และระบบไม่สามารถรักษากระบวนการเพียงพอที่จะโฮสต์บริการทั้งหมด กำลังทำงานในขณะนี้
โดยทั่วไป ให้หลีกเลี่ยงการใช้บริการถาวรเนื่องจากมีความต้องการใช้บริการอย่างต่อเนื่อง
ความทรงจำ เราขอแนะนำให้คุณใช้การติดตั้งแบบอื่น เช่น
WorkManager
หากต้องการดูข้อมูลเพิ่มเติม
เกี่ยวกับวิธีใช้ WorkManager
เพื่อตั้งเวลากระบวนการเบื้องหลัง ให้ดูที่
งานแบบถาวร
ใช้คอนเทนเนอร์ข้อมูลที่เพิ่มประสิทธิภาพ
ชั้นเรียนบางชั้นเรียนในภาษาโปรแกรมไม่ได้เพิ่มประสิทธิภาพสำหรับการใช้งานบนอุปกรณ์เคลื่อนที่
อุปกรณ์ ตัวอย่างเช่น ฟิลด์
การใช้งาน HashMap
อาจเป็นหน่วยความจำได้
ไม่มีประสิทธิภาพมากนัก เพราะต้องมีอ็อบเจ็กต์รายการแยกสำหรับการแมปทุกรายการ
เฟรมเวิร์ก Android มีคอนเทนเนอร์ข้อมูลที่เพิ่มประสิทธิภาพหลายรายการ ได้แก่
SparseArray
,
SparseBooleanArray
,
และ LongSparseArray
ตัวอย่างเช่น คลาส SparseArray
จะมีประสิทธิภาพมากกว่าเพราะหลีกเลี่ยง
จำเป็นต้อง
autobox
คีย์และบางครั้งก็เป็นค่า ซึ่งจะสร้างออบเจ็กต์อีก 1-2 รายการต่อหนึ่งรายการ
หากจำเป็น คุณสามารถเปลี่ยนไปใช้อาร์เรย์ดิบได้เสมอสำหรับโครงสร้างข้อมูลแบบ Lean
โปรดระมัดระวังการใช้การแยกความคิดของโค้ด
นักพัฒนาซอฟต์แวร์มักจะใช้บทคัดย่อเป็นแนวทางปฏิบัติในการเขียนโปรแกรมที่ดี เพราะสามารถปรับปรุงโค้ดได้ และการบำรุงรักษาได้อย่างยืดหยุ่น อย่างไรก็ตาม นามธรรมจะมีค่าใช้จ่ายสูงกว่ามาก มักต้องการโค้ดเพิ่มเติมที่ต้องดำเนินการ ซึ่งต้องใช้เวลาและ RAM มากขึ้นในการแมปข้อมูล โค้ดลงในหน่วยความจำ พยายามหลีกเลี่ยงสิ่งที่เป็นนามธรรมหากไม่ได้มีประโยชน์มากนัก
ใช้ Lite Probufs สำหรับข้อมูลแบบอนุกรม
โปรโตคอล บัฟเฟอร์ (Protobufs) เป็นกลไกการขยายตัวในภาษากลางๆ เป็นกลาง และขยายออกได้ ซึ่งออกแบบโดย Google สำหรับการจัดลําดับข้อมูลที่มีโครงสร้าง คล้ายกับ XML แต่เล็กลง เร็วขึ้น และง่ายขึ้น ถ้า คุณใช้ Protobuf สำหรับข้อมูล ให้ใช้ Lite Protobuf ในโค้ดฝั่งไคลเอ็นต์เสมอ เบนซินธรรมดา Protobufs สร้างโค้ดที่มีรายละเอียดมาก ซึ่งอาจก่อให้เกิดปัญหามากมายในแอปของคุณ เช่น การใช้ RAM เพิ่มขึ้น ขนาด APK เพิ่มขึ้นอย่างมาก และการดำเนินการที่ช้าลง
สำหรับข้อมูลเพิ่มเติม โปรดดู โปรโตบัฟ Readme
หลีกเลี่ยงการเลิกใช้งานหน่วยความจำ
เหตุการณ์การเก็บขยะจะไม่ส่งผลต่อประสิทธิภาพของแอป อย่างไรก็ตาม เหตุการณ์การเก็บขยะจำนวนมากที่เกิดขึ้นในช่วงเวลาสั้นๆ อาจทำให้แบตเตอรี่หมดเร็วและเพิ่มเวลาในการตั้งค่าเฟรมเล็กน้อยเนื่องจากการโต้ตอบที่จำเป็นระหว่างเครื่องมือเก็บขยะกับเธรดแอป ยิ่งระบบใช้เวลาในการเก็บขยะมาก แบตเตอรี่ก็จะยิ่งเร็วขึ้น การระบาย
บ่อยครั้งที่การเลิกใช้งานหน่วยความจำอาจทำให้เกิดเหตุการณ์การเก็บข้อมูลขยะจำนวนมาก ใน แต่ในทางปฏิบัติ การเลิกใช้งานหน่วยความจำจะอธิบายจำนวนออบเจ็กต์ชั่วคราวที่จัดสรรซึ่งเกิดขึ้นใน ระยะเวลา
ตัวอย่างเช่น คุณอาจจัดสรรออบเจ็กต์ชั่วคราวหลายรายการภายในลูป for
หรือ
คุณอาจสร้าง Paint
ใหม่หรือ
Bitmap
ออบเจ็กต์ภายใน
onDraw()
ฟังก์ชันของมุมมอง ในทั้ง 2 กรณี แอปจะสร้างวัตถุจำนวนมากอย่างรวดเร็วในปริมาณสูง เหล่านี้
สามารถใช้หน่วยความจำทั้งหมดที่มีในคนรุ่นใหม่ได้อย่างรวดเร็ว ทำให้สามารถเก็บขยะ
เหตุการณ์ที่กำลังจะเกิดขึ้น
ใช้เครื่องมือสร้างโปรไฟล์หน่วยความจำเพื่อค้นหาสถานที่ต่างๆ ใน โค้ดซึ่งมีการเลิกใช้งานหน่วยความจำสูงก่อนที่จะแก้ไขได้
หลังจากที่คุณระบุส่วนที่เป็นปัญหาในโค้ดแล้ว ให้ลองลดจำนวนการจัดสรรภายใน พื้นที่ที่สำคัญต่อประสิทธิภาพ ลองย้ายสิ่งต่างๆ ออกมาจากลูปภายในหรือย้ายสิ่งเหล่านั้นไปไว้ใน แบบจากโรงงาน ใหม่
และยังประเมินได้ด้วยว่าพูลออบเจ็กต์นั้นเป็นประโยชน์ต่อกรณีการใช้งานหรือไม่ ใช้ Object Pool แทน การวางอินสแตนซ์ของออบเจ็กต์ลงบนพื้น จะเป็นการปล่อยอินสแตนซ์ดังกล่าวลงในพูลเมื่อไม่จำเป็นต้องใช้อีกต่อไป ครั้งถัดไปที่ต้องใช้อินสแตนซ์ของออบเจ็กต์ประเภทดังกล่าว คุณจะรับอินสแตนซ์จากพูลได้ มากกว่าการจัดสรร
ประเมินประสิทธิภาพอย่างละเอียดเพื่อพิจารณาว่าออบเจ็กต์พูลเหมาะสมในสถานการณ์หนึ่งๆ หรือไม่ มีบางกรณีที่ Object Pool อาจทำให้ประสิทธิภาพแย่ลง แม้ว่าควรหลีกเลี่ยงสระว่ายน้ำ รวมถึงทำให้เกิดค่าใช้จ่ายอื่นๆ ด้วย ตัวอย่างเช่น การดูแลรักษาสระว่ายน้ำมักเกี่ยวข้องกับ การซิงค์ ซึ่งมีค่าใช้จ่ายในการดำเนินการที่ไม่สำคัญ นอกจากนี้ การล้างอินสแตนซ์ออบเจ็กต์ร่วมเพื่อ หลีกเลี่ยงการรั่วไหลของหน่วยความจำระหว่างรุ่น และการเริ่มต้นระหว่างการได้ผู้ใช้ใหม่อาจมีค่าที่ไม่ใช่ 0 โอเวอร์เฮด
การเก็บอินสแตนซ์ของออบเจ็กต์ในพูลมากกว่าที่จำเป็นก็สร้างภาระให้กับถังขยะเช่นกัน คอลเล็กชัน แม้ว่าพูลออบเจ็กต์จะลดจำนวนการเรียกใช้คอลเล็กชันขยะ แต่สุดท้ายแล้วพูลออบเจ็กต์ดังกล่าว จะเพิ่มปริมาณงานที่จำเป็นสำหรับการเรียกใช้ทุกครั้ง เนื่องจากเป็นสัดส่วนกับจำนวน ไบต์แบบสด (ที่เข้าถึงได้)
นำทรัพยากรและไลบรารีที่ใช้หน่วยความจำมากออก
ทรัพยากรและไลบรารีบางรายการภายในโค้ดอาจใช้หน่วยความจำโดยที่คุณไม่รู้ตัว ขนาดโดยรวมของแอป รวมถึงไลบรารีของบุคคลที่สามหรือทรัพยากรที่ฝังไว้ อาจส่งผลต่อปริมาณ หน่วยความจำที่แอปของคุณใช้ คุณสามารถปรับปรุงการใช้หน่วยความจำของแอป โดยนำรายการที่ซ้ำซ้อนออก คอมโพเนนต์หรือทรัพยากรและไลบรารีที่ไม่จำเป็นหรือมากเกินไปจากโค้ดของคุณ
ลดขนาดโดยรวมของ APK
คุณสามารถลดการใช้หน่วยความจำของแอปได้อย่างมากโดยการลดขนาดโดยรวมของแอป ขนาดบิตแมป ทรัพยากร เฟรมภาพเคลื่อนไหว และไลบรารีของบุคคลที่สามมีส่วนทำให้เกิดขนาดบิตแมป ของแอปของคุณ Android Studio และ Android SDK มีเครื่องมือมากมายที่จะลดขนาดของ ทรัพยากรและทรัพยากร Dependency ภายนอก เครื่องมือเหล่านี้รองรับวิธีการย่อโค้ดสมัยใหม่ เช่น การคอมไพล์ R8
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการลดขนาดแอปโดยรวม โปรดดู ลดขนาดแอป
ใช้ Hilt หรือ Dagger 2 เพื่อแทรก Dependency
เฟรมเวิร์กการแทรกทรัพยากร Dependency สามารถทำให้โค้ดที่คุณเขียนง่ายขึ้นและมีการปรับเปลี่ยน ที่เป็นประโยชน์สำหรับการทดสอบและการเปลี่ยนแปลงการกำหนดค่าอื่นๆ
หากต้องการใช้เฟรมเวิร์กการแทรกทรัพยากร Dependency ในแอป ให้พิจารณาใช้ Hilt หรือ กริช Hilt เป็นการแทรกทรัพยากร Dependency ไลบรารีสำหรับ Android ที่ทำงานบน Dagger กริชไม่ใช้ภาพสะท้อนในการสแกนแอปของคุณ โค้ด คุณสามารถใช้เวลาคอมไพล์แบบคงที่ของ Dagger ในแอป Android ได้โดยไม่จำเป็น ค่าใช้จ่ายหรือการใช้งานหน่วยความจำในช่วงรันไทม์
เฟรมเวิร์กการแทรกทรัพยากร Dependency อื่นๆ ที่ใช้การสะท้อนความรู้สึกจะเริ่มต้นกระบวนการด้วยการสแกน สำหรับคำอธิบายประกอบ ขั้นตอนนี้อาจทำให้ต้องใช้รอบ CPU และ RAM มากขึ้นอย่างมาก และอาจทำให้เกิด เวลาหน่วงที่สังเกตเห็นได้ชัดเมื่อเปิดแอป
โปรดระมัดระวังการใช้ไลบรารีภายนอก
โค้ดไลบรารีภายนอกมักไม่ได้เขียนขึ้นสำหรับสภาพแวดล้อมอุปกรณ์เคลื่อนที่ และอาจทำงานในไคลเอ็นต์บนอุปกรณ์เคลื่อนที่อย่างไม่มีประสิทธิภาพ เมื่อใช้ไลบรารีภายนอก คุณอาจต้องเพิ่มประสิทธิภาพ สำหรับอุปกรณ์เคลื่อนที่ วางแผนงานนี้ล่วงหน้า และวิเคราะห์ไลบรารีในแง่ของ ขนาดโค้ดและรอยเท้า RAM ก่อนที่จะใช้งาน
ไลบรารีที่เพิ่มประสิทธิภาพสำหรับอุปกรณ์เคลื่อนที่บางรายการอาจทำให้เกิดปัญหาเนื่องจากมีการใช้งานที่แตกต่างกัน สำหรับ ตัวอย่างเช่น ไลบรารีหนึ่งอาจใช้ Protobufs แบบ Lite ขณะที่อีกรายการใช้ Micro produfs การติดตั้งใช้งาน Protobuf แบบต่างๆ ในแอป ซึ่งอาจเกิดขึ้นได้เมื่อใช้ การบันทึก, การวิเคราะห์, เฟรมเวิร์กการโหลดรูปภาพ, การแคช และอื่นๆ อีกมากมายที่คุณไม่คาดคิด
แม้ว่า ProGuard สามารถช่วยนำ API และทรัพยากรออกได้ด้วย
แฟล็กที่ถูกต้อง จะนําทรัพยากร Dependency ภายในขนาดใหญ่ของไลบรารีออกไม่ได้ ฟีเจอร์ที่ต้องการใช้งาน
ไลบรารีเหล่านี้อาจต้องใช้ทรัพยากร Dependency ระดับล่าง ซึ่งจะเป็นปัญหาโดยเฉพาะอย่างยิ่งเมื่อคุณ
ใช้คลาสย่อย Activity
จาก
ไลบรารีที่สามารถมีทรัพยากร Dependency ต่างๆ มากมาย เมื่อไลบรารีใช้การสะท้อน
เป็นเรื่องปกติและต้องปรับแต่ง ProGuard ด้วยตนเองเพื่อให้ใช้งานได้
หลีกเลี่ยงการใช้ไลบรารีที่ใช้ร่วมกันสำหรับฟีเจอร์เพียง 1 หรือ 2 รายการในหลายสิบรายการ อย่าดึงข้อมูลขนาดใหญ่ จำนวนเงินและค่าใช้จ่ายในการดำเนินการที่คุณไม่ได้ใช้ เมื่อคุณพิจารณาว่าจะใช้ไลบรารีหรือไม่ ให้มองหา การติดตั้งใช้งานที่ตรงกับความต้องการของคุณมากที่สุด มิฉะนั้น คุณอาจตัดสินใจที่จะสร้าง ของตัวเอง