CHƯƠNG 1:TỔNG QUAN VỀ HIỆU NĂNG CỦA ỨNG DỤNG 1.1Khái niệm Hiệu năng của ứng dụng là tính chất thể hiện mức độ hiệu quả trong việc thực thi mã lệnh của ứng dụng, được đặc trưng bởi số lượng công việc mà ứng dụng thực hiện được trong một khoảng thời gian và với một lượng tài nguyên máy tính. Hiệu năng của ứng dụng thường bị ảnh hưởng bởi rất nhiều yếu tố ví dụ như CPU, bộ nhớ Ram, đường truyền mạng, độ phân giải của màn hình. Tuy nhiên, để đánh giá hiệu năng của ứng dụng thì ta thường đánh giá dựa vào 3 yếu tố chính: bộ nhớ, CPU và đường truyền mạng.2 Tầm quan trọng Một câu hỏi đã được đặt ta tại Localytics : Người sử dụng ứng dụng đã bỏ đi đâu? (Localytics là một công ty chuyên phân tích dữ liệu người dùng với nền tảng là mobile engagement). Với bộ dữ liệu khổng lồ gồm 2,7 tỷ thiết bị, 37.000 ứng dụng mobile và web.
Mỗi tháng, Localytics lại thực hiện hơn 120 tỷ dữ liệu điểm. Họ đã khảo sát người dùng vào 3 mốc thời gian là 30 ngày, 60 ngày, 90 ngày sau khi tải ứng dụng về. Và có được kết quả đáng kinh ngạc sau: - Tỷ lệ giữ chân người dùng trong 1 tháng sau khi tải, đã rớt từ 42% xuống còn 37%. Đến tháng thứ 3, số lượng users thay đổi app tăng từ 75% lên 80%.1 Tỉ lệ trung bình sử dụng ứng dụng 10 Theo số liệu (hình 1.các ứng dụng Media & Entertainment có tỷ lệ giữ chân người sử dụng cao nhất qua 3 tháng đầu với 40% người dùng trở lại với ứng dụng ngay trong tháng đầu tiên.
Đây là điều không quá bất ngờ vì sự ra đời của web và các ứng dụng di động đang dẫn đầu cách thức nghe nhạc, tiếp nhận thông tin, xem video/TV và đọc tin. Trong khi đó, các ứng dụng Game tiếp tục vật lộn để giữ người dùng, khi có tỷ lệ giữ chân trung bình thấp nhất trong 3 tháng đầu tiên.2 Tỉ lệ sử dụng ứng dụng trong 3 tháng Theo số liệu (hình 1.3), đã có sự khác biệt rõ nét giữa các ứng dụng hiệu suất cao với thị trường chung. Đây là những ứng dụng nổi tiếng, được nhiều người tin tưởng và xây dựng được 1 lớp người sử dụng lớn 11 Hình 1.3 Tỉ lệ sử dụng ứng dụng tần suất cao sau 3 tháng Qua những số liệu trên, một phần nào đó các ứng dụng đang thất bại trong việc mang đến những trải nghiệm chất lượng cao, đáp ứng được mong đợi của người dùng. Mặc dù di động vẫn giữ được vị thế tương tác với nhiều thương hiệu, nhưng các thương hiệu lại không làm tròn phần trách nhiệm của mình.
Hệ quả là người dùng đang thay đổi 1 cách chóng mặt. Vậy ta có thể trả lời câu hỏi ở phía trên, đó là: Người dùng đang hướng tới những sản phẩm mang lại cho họ trải nghiệm tuyệt vời, hay nói cách khác, Hiệu năng của ứng dụng đang dần trở thành chìa khóa chính để giữ chân những người khách hàng khó tính. MỘT SỐ PHƯƠNG PHÁP GIÚP TỐI ƯU HÓA HIỆU NĂNG CỦA ỨNG DỤNG 2.1 Tối ưu hóa mã nguồn Ngôn ngữ lập trình java được phát triển bởi Sun MicroSystems do Jame Gosling khởi xướng và phát hành năm 1995. Với ưu thế đa nền tảng, Java ngày càng được áp dụng rộng rãi trên nhiều thiết bị từ máy tính đến mobile và nhiều thiết bị phần cứng khác… Tối ưu hóa mã nguồn được nêu ra đầu tiên nhưng đây không phải là ưu tiên hàng đầu trong việc tạo ra các ứng dụng.
Trong thực tế, việc đáp ứng các yêu cầu từ phía người dùng mới là ưu tiên hàng đầu, còn việc tối ưu mã nguồn lại được đánh giá với độ ưu tiên thấp hơn. Sau đây chúng ta sẽ đi tìm hiểu một số phương pháp nhằm tối ưu hóa mã nguồn: 2.1 Bộ nhớ cache CPU cache [9], [10]là bộ nhớ dùng bởi bộ xử lý trung tâm của máy tính nhằm giảm thời gian truy cập dữ liệu trung bình từ bộ nhớ chính. Cache là bộ nhớ nhỏ hơn, nhanh hon và lưu trữ bản sao của những dữ liệu thường xuyên được truy cập trên bộ nhớ chính. Hầu hết CPU đều có các bộ nhớ cache độc lập khác nhau, bao gồm cache chỉ dẫn và cache dữ liệu, nơi mà dữ liệu được xếp thành nhiều lớp khác nhau.1 Cấu trúc vật lý hệ thống [10] Một lớp đáng nói ở đây đó là android.LruCache<K, V> [9],[10], được giới thiệu trong phiên bản Android 3.
Xét một ví dụ nhỏ để 13 hiểu được tác dụng của nó: giả sử chúng ta muốn tải một ảnh cho ứng dụng của bạn. Tuy nhiên, điện thoại lại bị hết bộ nhớ.Bạn không thể tải ảnh mới nếu như không xóa một số ảnh hiện có mà bạn đã tải trước đó.2 Cách tải và hiển thị ảnh thủ công[10] 14 Hình 2.3 Sử dụng bộ nhớ cache [10] Hai hình trên ta có thể thấy cách mà chúng ta sử dụng bộ nhớ cache, nó là vô cùng hiệu quả. Vậy sẽ ra sao nếu bộ nhớ cache đầy, khi chúng ta không thể tải thêm ảnh vào đó nữa?Chúng ta sẽ phải loại bỏ những ảnh nào?Và loại bỏ bằng cách nào? Câu trả lời đó là loại bỏ đi những đối tượng không cần thiết hay đơn giản hơn là những đối tượng ít được sử dụng trong một khoảng thời gian Hình 2.4 Cách hoạt động của Lru [10] Và thuật toán sắp xếp các đối tượng như vậy được gọi là Lru (Least Recetly Used). Và việc bây giờ đơn giản là loại bỏ khi cần thiết các đối tượng nằm ở phía sau.
Các đối tượng càng nằm trên thì cơ hội sử dụng trong tương lai càng lớn. 15 Theo mặc định, kích thước bộ nhớ cache được đo bằng số lượng các mục. Ghi đè sizeof (K, V) kích thước bộ nhớ cache trong các đơn vị khác nhau. Ví dụ, bộ nhớ cache này được giới hạn 4MiB bitmap: int cacheSize = 4*1024; //4MiB LruCache <String, Bitmap> bitmapCache = newLruCache<String, Bitmap> (cacheSize){ protectedint sizeOf(String key, Bitmap value) { Return value.2 StrictMode StrictMode [8] là một công cụ phát triển trong đó phát hiện những thứ có thể gây ra lỗi trong ứng dụng của bạn, do đó bạn có thể sửa chữa chúng.
StrictMode thường được sử dụng trong việc phát hiện và bắt lỗi truy cập mạng hoặc ổ đĩa trong hàm Main Thread, nơi mà các hoạt động giao diện của người dùng diễn ra. Có ví dụ về kích hoạt StrictMode: publicvoid onCreate(){ If (DEVELOPER_MODE){ StrictMode.2 Sử dụng bộ nhớ một cách hiệu quả Android không cung cấp không gian trao đổi về bộ nhớ, nhưng nó sử dụng phân trang và bộ nhớ, lập bản đồ (mmapping) để quản lý bộ nhớ. Điều này có nghĩa rằng bất kỳ bộ nhớ bạn sửa đổi cho dù bằng cách phân bổ các đối tượng mới hoặc mmapped chạm trang-vẫn thường trú trong bộ nhớ RAM vàkhông thể được paged ra. Vì vậy, cách duy nhất để hoàn toàn giải phóng bộ nhớ từ ứng dụng của bạn là để phát hành tài liệu tham khảo đối tượng bạn có thể nắm giữ, làm cho bộ nhớ có sẵn để thu gom rác.
Đó là với một ngoại lệ: bất kỳ tập tin mmapped trong mà không sửa đổi, chẳng hạn như mã số, có thể được paged ra RAM nếu hệ thống muốn sử dụng bộ nhớ mà ở nơi khác. Để cân bằng bộ nhớ, Android cố gắng tối ưu hóa số lượng trang bộ nhớ với số tiến trình thông qua các cách sau [8]: - Tiến trình ứng dụng là một tiến trình con được phân chia (fork) từ một tiến trình có tên Zygote, hay nói cách khác Zygote là tiến trình cha của mọi tiến trình ứng dụng. Zygote được khởi chạy khi hệ thống khởi động. Để khởi tạo một tiến trình ứng dụng mới, hệ thống tạo một tiến trình con từ Zygote, tải và chạy code của ứng dụng.
Chính nhờ đó mà các tiến trình ứng dụng sử dụng và kế thừa bộ nhớ cũng như các tài nguyên từ tiến trình Zygote. - Dữ liệu tĩnh, dữ liệu sử dụng chung nhất được quản lý bởi tiến trình cha, điều này cho phép dữ liệu được sử dụng và chia sẻ giữa các tiến trình con. Một số dữ liệu tĩnh như Dalvik code (file .odex), tài nguyên ứng dụng (tài nguyên trong các file .apk) hay thư viện code (file. - Android phân bổ bộ nhớ động giữa các tiến trình bằng cách chỉ định chính xác vùng bộ nhớ được chia sẻ sử dụng ashmem hoặc gralloc.
Ví dụ như bộ 17 nhớ con trỏ sử dụng phần bộ nhớ dùng chung với Content Provider hay window surfaces sử dụng phần bộ nhớ dùng chung với bộ nhớ ứng dụng. - Việc chia sẻ bộ nhớ giữa các ứng dụng được sử dụng rộng rãi trong Android, vì vậy việc theo dõi, đo đạc bộ nhớ sử dụng là hết sức cần thiết. Android SDK cung cấp công cụ cho phép thực hiện việc này như logcat, monitor tool, dumpsys.5 Mô hình chia sẻ bộ nhớ [8] 2.2 Cấp phát và thu hồi bộ nhớ Android sử dụng một số cách thức sau để cấp phát và thu hồi bộ nhớ [8]: - Davik VM cung cấp phạm vi cho bộ nhớ heap với từng tiến trình. Bộ nhớ heap có thể tăng lên nhưng chỉ tới một giới hạn mà hệ thống cho phép.
- Android sử dụng giá trị PSS của HĐH Linux (Proportional Set Size) để xác định số page mà tiến trình đang chiếm giữ (cả private page và share page). Thông số này giúp tính toán xem giá trị thực sự của bộ nhớ mà tiến trình 18 chiếm giữ. Đồng nghĩa với đó, Android cũng đánh giá được khi nào thì tiến trình có thể bị kill do chiếm giữ quá nhiều bộ nhớ. - Sau khi bộ dọn rác (GC) hoạt động Davik VM tìm các page không được sử dụng và giải phóng nó.
Chúng ta có thể hình dung quá trình hoạt động của GC như sau: Khi chương trình khởi chạy thì một vùng nhớ liên tục còn trống sẽ được dành riêng để cấp phát cho các biến trong chương trình (vùng nhớ này được gọi là managed-heap). Khi chúng ta dùng toán tử new để tạo một đối tượng mới thì chương trình sẽ kiểm tra xem vùng nhớ này còn đủ để cấp phát hay không, nếu không đủ thì GC sẽ được khởi động. Bước đầu tiên mà GC thực hiện là tạm dừng chương trình và thực hiện việc duyệt để đánh dấu tất cả những vùng nhớ đang được sử dụng với khởi đầu tại một điểm nào đó đã biết trước (hay được gọi là điểm gốc).6 Cơ chế đánh dấu điểm gốc tham chiếu 19 Như hình trên, chúng ta thấy rằng chương trình này có một số điểm gốc tham chiếu tới các đối tượng F, D, C và A. GC sẽ bắt đầu tại 1 điểm gốc nào đó tham chiếu tới D, GC sẽ đánh dấu D là “còn sống“.