หน้านี้จะอธิบายวิธีลดการใช้หน่วยความจำภายในแอปของคุณอย่างสม่ำเสมอ ดูข้อมูลเกี่ยวกับวิธีที่ระบบปฏิบัติการ 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
มีประสิทธิภาพมากกว่าเนื่องจากหลีกเลี่ยงไม่ให้ระบบต้องใส่กล่องข้อความอัตโนมัติสำหรับคีย์และบางครั้งก็เป็นค่า ซึ่งจะสร้างออบเจ็กต์อีก 1-2 รายการต่อรายการ
คุณเปลี่ยนไปใช้อาร์เรย์ดิบสำหรับโครงสร้างข้อมูลที่มีประสิทธิภาพได้เสมอหากจำเป็น
โปรดระมัดระวังการใช้การแยกความคิดของโค้ด
นักพัฒนาซอฟต์แวร์มักใช้การแยกความคิดเป็นแนวทางการเขียนโปรแกรมที่ดี เนื่องจากช่วยเพิ่มความยืดหยุ่นและการบำรุงรักษาโค้ดได้ อย่างไรก็ตาม นามธรรมจะมีค่าใช้จ่ายสูงกว่ามาก มักต้องการโค้ดเพิ่มเติมที่ต้องดำเนินการ ซึ่งต้องใช้เวลาและ RAM มากขึ้นในการแมปข้อมูล โค้ดลงในหน่วยความจำ พยายามหลีกเลี่ยงสิ่งที่เป็นนามธรรมหากไม่ได้มีประโยชน์มากนัก
ใช้ Lite Probufs สำหรับข้อมูลแบบอนุกรม
โปรโตคอล บัฟเฟอร์ (Protobufs) เป็นกลไกการขยายตัวในภาษากลางๆ เป็นกลาง และขยายได้อย่างกว้างขวาง ซึ่งออกแบบโดย Google สำหรับการจัดลําดับข้อมูลที่มีโครงสร้าง คล้ายกับ XML แต่เล็กลง เร็วขึ้น และง่ายขึ้น หากใช้ protobuf สำหรับข้อมูล ให้ใช้ protobuf เวอร์ชัน Lite ในโค้ดฝั่งไคลเอ็นต์เสมอ โปรโตคอลแบบทั่วไปจะสร้างโค้ดที่ละเอียดมาก ซึ่งอาจทำให้เกิดปัญหามากมายในแอป เช่น การใช้ RAM เพิ่มขึ้น การเพิ่มขนาด APK อย่างมาก และการดำเนินการที่ช้าลง
สำหรับข้อมูลเพิ่มเติม โปรดดู โปรโตบัฟ Readme
หลีกเลี่ยงการเสียหน่วยความจำ
เหตุการณ์การเก็บขยะจะไม่ส่งผลต่อประสิทธิภาพของแอป อย่างไรก็ตาม การเก็บขยะจำนวนมาก เหตุการณ์ที่เกิดขึ้นในช่วงเวลาสั้นๆ อาจทำให้แบตเตอรี่หมดอย่างรวดเร็ว รวมถึง เพิ่มเวลาในการตั้งค่าเฟรมเนื่องจากการโต้ตอบที่จำเป็นระหว่างเครื่องมือเก็บขยะกับ เทรดของแอป ยิ่งระบบใช้เวลาในการรวบรวมขยะมากเท่าใด แบตเตอรี่ก็จะหมดเร็วขึ้นเท่านั้น
การเปลี่ยนแปลงของหน่วยความจํามักทําให้เหตุการณ์การเก็บขยะเกิดขึ้นจํานวนมาก ใน แต่ในทางปฏิบัติ การเลิกใช้งานหน่วยความจำจะอธิบายจำนวนออบเจ็กต์ชั่วคราวที่จัดสรรซึ่งเกิดขึ้นใน ระยะเวลา
ตัวอย่างเช่น คุณอาจจัดสรรออบเจ็กต์ชั่วคราวหลายรายการภายในลูป for
หรือ
คุณอาจสร้าง Paint
ใหม่หรือ
Bitmap
ออบเจ็กต์ภายใน
onDraw()
ฟังก์ชันของมุมมอง ทั้งสองกรณี แอปสร้างวัตถุจำนวนมากอย่างรวดเร็วในปริมาณสูง รายการเหล่านี้อาจใช้หน่วยความจำทั้งหมดที่มีอยู่ในรุ่นใหม่อย่างรวดเร็ว ซึ่งจะบังคับให้เหตุการณ์การเก็บขยะเกิดขึ้น
ใช้เครื่องมือสร้างโปรไฟล์หน่วยความจำเพื่อค้นหาสถานที่ต่างๆ ใน โค้ดซึ่งมีการเลิกใช้งานหน่วยความจำสูงก่อนที่จะแก้ไขได้
หลังจากระบุพื้นที่ที่เป็นปัญหาในโค้ดแล้ว ให้ลองลดจำนวนการจัดสรรภายในพื้นที่ที่ส่งผลต่อประสิทธิภาพ ลองย้ายสิ่งต่างๆ ออกมาจากลูปภายในหรือย้ายสิ่งเหล่านั้นไปไว้ใน แบบจากโรงงาน ใหม่
และยังประเมินได้ด้วยว่าพูลออบเจ็กต์นั้นเป็นประโยชน์ต่อกรณีการใช้งานหรือไม่ ใช้ Object Pool แทน การวางอินสแตนซ์ของออบเจ็กต์ลงบนพื้น จะเป็นการปล่อยอินสแตนซ์ดังกล่าวลงในพูลเมื่อไม่จำเป็นต้องใช้อีกต่อไป ครั้งถัดไปที่ต้องใช้อินสแตนซ์ของออบเจ็กต์ประเภทดังกล่าว คุณจะรับอินสแตนซ์จากพูลได้ มากกว่าการจัดสรร
ประเมินประสิทธิภาพอย่างละเอียดเพื่อพิจารณาว่าพูลออบเจ็กต์เหมาะกับสถานการณ์หนึ่งๆ หรือไม่ มีหลายกรณีที่พูลออบเจ็กต์อาจทําให้ประสิทธิภาพแย่ลง แม้ว่าพูลจะหลีกเลี่ยงการจัดสรร แต่ก็มีค่าใช้จ่ายอื่นๆ เพิ่มเติม ตัวอย่างเช่น การดูแลรักษาพูลมักจะเกี่ยวข้องกับการซิงค์ ซึ่งอาจมีค่าใช้จ่ายเพิ่มเติมที่ไม่ควรมองข้าม นอกจากนี้ การล้างอินสแตนซ์ออบเจ็กต์ร่วมเพื่อ หลีกเลี่ยงการรั่วไหลของหน่วยความจำระหว่างรุ่น และการเริ่มต้นระหว่างการได้ผู้ใช้ใหม่อาจมีค่าที่ไม่ใช่ 0 โอเวอร์เฮด
การเก็บอินสแตนซ์ออบเจ็กต์ในพูลไว้มากกว่าที่จำเป็นยังทำให้การรวบรวมขยะหนักขึ้นด้วย แม้ว่าพูลออบเจ็กต์จะลดจำนวนการเรียกใช้คอลเล็กชันขยะ แต่สุดท้ายแล้วพูลออบเจ็กต์ดังกล่าว จะเพิ่มปริมาณงานที่จำเป็นสำหรับการเรียกใช้ทุกครั้ง เนื่องจากเป็นสัดส่วนกับจำนวน ไบต์แบบสด (ที่เข้าถึงได้)
นำทรัพยากรและไลบรารีที่ใช้หน่วยความจำมากออก
ทรัพยากรและไลบรารีบางอย่างในโค้ดอาจใช้หน่วยความจําโดยที่คุณไม่รู้ตัว ขนาดโดยรวมของแอป รวมถึงไลบรารีของบุคคลที่สามหรือทรัพยากรที่ฝังไว้ อาจส่งผลต่อปริมาณ หน่วยความจำที่แอปของคุณใช้ คุณสามารถปรับปรุงการใช้หน่วยความจำของแอปได้โดยการนำคอมโพเนนต์ที่ซ้ำซ้อน ไม่จำเป็น หรือมีขนาดใหญ่เกินไป หรือทรัพยากรและไลบรารีออกจากโค้ด
ลดขนาดโดยรวมของ APK
คุณสามารถลดการใช้หน่วยความจำของแอปได้อย่างมากโดยการลดขนาดโดยรวมของแอป ขนาดบิตแมป ทรัพยากร เฟรมภาพเคลื่อนไหว และไลบรารีของบุคคลที่สามมีส่วนทำให้เกิดขนาดบิตแมป ของแอปของคุณ Android Studio และ Android SDK มีเครื่องมือมากมายที่จะลดขนาดของ ทรัพยากรและทรัพยากร Dependency ภายนอก เครื่องมือเหล่านี้รองรับวิธีการบีบอัดโค้ดสมัยใหม่ เช่น การคอมไพล์ R8
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการลดขนาดแอปโดยรวม โปรดดู ลดขนาดแอป
ใช้ Hilt หรือ Dagger 2 เพื่อแทรก Dependency
เฟรมเวิร์กการแทรกทรัพยากร Dependency จะลดความซับซ้อนของโค้ดที่คุณเขียนและมีการปรับเปลี่ยน ที่เป็นประโยชน์สำหรับการทดสอบและการเปลี่ยนแปลงการกำหนดค่าอื่นๆ
หากต้องการใช้เฟรมเวิร์กการฉีดข้อมูลในแอป ให้พิจารณาใช้ Hilt หรือ Dagger Hilt เป็นไลบรารีการฉีดข้อมูลสำหรับ Android ที่ทำงานบน Dagger Dagger ไม่ได้ใช้การสะท้อนเพื่อสแกนโค้ดของแอป คุณสามารถใช้การติดตั้งใช้งานแบบคงที่ของ Dagger ในเวลาคอมไพล์ในแอป Android ได้โดยไม่ต้องเสียค่าใช้จ่ายรันไทม์หรือการใช้หน่วยความจำโดยไม่จำเป็น
เฟรมเวิร์กการแทรกทรัพยากร Dependency อื่นๆ ที่ใช้การสะท้อนความรู้สึกจะเริ่มต้นกระบวนการด้วยการสแกน สำหรับคำอธิบายประกอบ กระบวนการนี้อาจต้องใช้รอบการทำงานของ CPU และ RAM มากขึ้นอย่างมาก และอาจทำให้เกิดความล่าช้าที่เห็นได้ชัดเมื่อแอปเปิดขึ้น
โปรดระมัดระวังเกี่ยวกับการใช้ไลบรารีภายนอก
โค้ดไลบรารีภายนอกมักไม่ได้เขียนขึ้นสำหรับสภาพแวดล้อมอุปกรณ์เคลื่อนที่ และอาจทำงานบนไคลเอ็นต์อุปกรณ์เคลื่อนที่ได้อย่างไม่มีประสิทธิภาพ เมื่อใช้ไลบรารีภายนอก คุณอาจต้องเพิ่มประสิทธิภาพ สำหรับอุปกรณ์เคลื่อนที่ วางแผนงานนี้ล่วงหน้า และวิเคราะห์ไลบรารีในแง่ของ ขนาดโค้ดและรอยเท้า RAM ก่อนที่จะใช้งาน
ไลบรารีที่เพิ่มประสิทธิภาพสำหรับอุปกรณ์เคลื่อนที่บางรายการอาจทำให้เกิดปัญหาเนื่องจากมีการใช้งานที่แตกต่างกัน สำหรับ ตัวอย่างเช่น ไลบรารีหนึ่งอาจใช้ Protobufs แบบ Lite ขณะที่อีกรายการใช้ Micro produfs การติดตั้งใช้งาน Protobuf แบบต่างๆ ในแอป ซึ่งอาจเกิดขึ้นได้เมื่อใช้ การบันทึก, การวิเคราะห์, เฟรมเวิร์กการโหลดรูปภาพ, การแคช และอื่นๆ อีกมากมายที่คุณไม่คาดคิด
แม้ว่า ProGuard จะช่วยนำ API และทรัพยากรออกได้โดยใช้ Flag ที่ถูกต้อง แต่จะนำการพึ่งพาภายในขนาดใหญ่ของไลบรารีออกไม่ได้ ฟีเจอร์ที่คุณต้องการในไลบรารีเหล่านี้อาจต้องใช้ทรัพยากร Dependency ในระดับที่ต่ำกว่า ซึ่งจะเป็นปัญหาโดยเฉพาะอย่างยิ่งเมื่อคุณ
ใช้คลาสย่อย Activity
จาก
ไลบรารีที่สามารถมีทรัพยากร Dependency ต่างๆ มากมาย เมื่อไลบรารีใช้การสะท้อน
เป็นเรื่องปกติและต้องปรับแต่ง ProGuard ด้วยตนเองเพื่อให้ใช้งานได้
หลีกเลี่ยงการใช้ไลบรารีที่ใช้ร่วมกันสำหรับฟีเจอร์เพียง 1-2 รายการจากหลายสิบรายการ อย่าดึงข้อมูลขนาดใหญ่ จำนวนเงินและค่าใช้จ่ายในการดำเนินการที่คุณไม่ได้ใช้ เมื่อคุณพิจารณาว่าจะใช้ไลบรารีหรือไม่ ให้มองหา การติดตั้งใช้งานที่ตรงกับความต้องการของคุณมากที่สุด หรือคุณอาจเลือกสร้างการใช้งานของคุณเอง