Có rất nhiều hướng dẫn về tăng hiệu suất Android và tối ưu hóa hệ thống. Một số hợp lý, nhưng nhiều cái khác chỉ dựa trên lý thuyết, phương pháp lỗi thời hoặc đơn giản là vô nghĩa. Điều này bao gồm khuyến nghị về swap, thêm giá trị vào build.prop, và thay đổi biến trong kernel Linux.
Thậm chí còn có hàng tá "script tối ưu hóa" - file .zip flashable all-in-one hứa hẹn tăng hiệu suất, pin và nhiều thứ khác. Một số tweak có thể hoạt động, nhưng phần lớn chỉ là hiệu ứng placebo, thậm chí còn ảnh hưởng xấu đến thiết bị.
Không có nghĩa là mọi người cố ý phát hành script độc hại - xác thực có ứng dụng trả phí giả mạo trên Play Store, nhưng các script tối ưu trên diễn đàn Android thường có ý định tốt, chỉ là dev có thể bị misinformed hoặc đang thử nghiệm. Thật đáng buồn, hiệu ứng "tuyết cuộn" thường xảy ra, đặc biệt trong script "all-in-one". Một vài tweak có thể làm việc gì đó, trong khi bộ tweak khác không làm gì cả - nhưng các script này được truyền tai nhau như "vũ khí thần thánh" mà không ai kiểm tra thực tế gì hoạt động, gì không.
Do đó, hầu hết script "all-in-one" dùng các phương pháp tương tự, một số đã lỗi thời hoặc có hại lâu dài. Tóm lại, phần lớn script này chỉ là tập hợp các cấu hình khuyến nghị được ghép lả, không hiểu rõ cách hoặc tại sao chúng "hoạt động" - user flash script, nói hiệu năng tăng vọt (khi thực tế, khả năng cao chỉ do đơn giản khởi động lại thiết bị làm dọn RAM).
Trong bài viết độc quyền này, chúng tôi sẽ phân tích các khuyến nghị phổ biến nhất về "tối ưu" hiệu suất Android, xem chúng là huyền thoại hay tweak hợp pháp.
Swap
Đứng đầu danh sách huyền thoại là Android swap - điều hoàn toàn vô lý khi được coi là tối ưu. Mục đích chính của swap là tạo và kết nối file paging để giải phóng không gian bộ nhớ. Nghe có vẻ hợp lý trên giấy, nhưng thực tế chỉ áp dụng cho server, nơi gần như không có tương tác người dùng.
Khi bạn dùng swap thường xuyên trên Android, nó dẫn đến lag nghiêm trọng do dữ liệu trượt qua cache. Ví dụ: một app cố gắng hiển thị đồ họa lưu trong swap, giờ phải tải lại disk sau khi giải phóng không gian bằng cách đổi dữ liệu swap với app khác. Rất hỗn loạn.
Một số fan hâm mộ tối ưu nói swap không gây vấn đề, nhưng không phải swap tạo ra boost hiệu năng - đó là cơ chế built-in Android lowmemorykiller (LMK), thường xuyên kill các tiến trình ưu tiên cao, phồng to, không được dùng. LMK được thiết kế riêng cho điều kiện thiếu bộ nhớ, được gọi từ tiến trình kswapd, và thường kill tiến trình user space. Khác với OOMkiller (out-of-memory killer), nhưng đó là chủ đề khác.
Điểm mấu chốt: thiết bị có 1GB RAM không bao giờ đạt hiệu năng cần thiết qua swap, nên swap hoàn toàn không cần thiết trên Android. Việc triển khai nó chỉ gây lag và giảm sút hiệu năng thay vì tối ưu.
zRAM – Đã lỗi thời và không còn hiệu quả
zRAM là phương pháp tối ưu chứng minh được, nhưng cho thiết bị cũ - những thiết bị chạy KitKat với khoảng 512MB RAM. Việc mọi người vẫn đưa zRAM vào script tối ưu hay khuyến nghị như tweak hiện đại cho thấy mọi người không theo dõi giao thức vận hành mới nhất.
zRAM dành cho SoC đa nhân tầm thấp giá rẻ (như chipset MTK với 512MB RAM). Các điện thoại Trung Quốc rẻ tiền cơ bản. zRAM tách kernel qua luồng mã hóa.
Khi dùng zRAM trên thiết bị cũ single core, ngay cả khi được khuyến nghị, lag lớn vẫn xuất hiện. Tương tự công nghệ KSM (Kernel Same Page Merging) gộp các trang bộ nhớ trùng lặp để giải phóng không gian. Google khuyến nghị điều này, nhưng gây lag lớn trên thiết bị cũ vì luồng core liên tục chạy tìm trang trùng lặp. Thử tối ưu lại làm chậm thiết bị thêm, một sự vi ngẫu.
Seeder – Đã lỗi thời kể từ Android 3.0
Một trong những mẹo tối ưu tranh cãi nhất là seeder. Chắc ai đó có thể cố chứng minh chúng tôi sai, nhưng trước hãy xem lịch sử seeder.
Có nhiều báo cáo nói hiệu năng tốt hơn sau khi cài trên thiết bị Android cũ rất nhiều. Tuy nhiên, mọi người tin rằng điều đó có nghĩa là nó cũng áp dụng cho thiết bị Android hiện đại, điều hoàn toàn vô lý. Việc Seeder vẫn được duy trì và quảng cáo như công cụ "giảm lag hiện đại" là ví dụ của tin sai lệch - dù không phải lỗi của dev Seeder, vì trang Play Store của họ ghi rõ Seeder kém hiệu quả sau Android 4.0+. Tuy nhiên, Seeder vẫn xuất hiện trong thảo luận tối ưu cho Android hiện đại.
Seeder trên Android 3.0 khắc phục bug nơi Android runtime chủ động dùng file /dev/random/ để lấy entropy. Buffer /dev/random/ trở nên không ổn định, hệ thống bị chặn cho đến khi điền đủ dữ liệu - như các cảm biến, nút bấm nhỏ.
Tác giả Seeder lấy Linux-daemon rngd, compile cho Android inastroil để lấy dữ liệu ngẫu nhiên từ /dev/urandom nhanh và dự đoán được hơn, hợp nhất vào dev/random/ mỗi giây, không cho /dev/random/ cạn kiệt. Kết quả: Android không thiếu entropy, chạy mượt hơn.
Google đã fix bug này sau Android 3.0, nhưng Seeder vẫn xuất hiện trong danh sách "tweak khuyến nghị" cho tối ưu Android. Hơn nữa, app Seeder có một vài analogue như sEFix bao gồm chức năng Seeder, dù dùng cùng rngd hoặc haveged thay thế, hoặc chỉ symlink giữa /dev/urandom và /dev/random. Điều này hoàn toàn vô nghĩa trên Android hiện đại.
Lý do vô nghĩa: Android mới dùng /dev/random/ trong 3 thành phần chính - libcrypto (mã hóa SSL, tạo SSH key...), WPA_supplication/hostapd (tạo key WEP/WPA), và một vài thư viện tạo ID cho file system EXT2/EXT3/EXT4.
Khi Seeder hoặc bản nâng cấp dựa trên Seeder được đưa vào script tối ưu hiện đại, kết quả là giảm sút hiệu năng, vì rngd sẽ liên tục đánh thức thiết bị, tăng tần số CPU, tiêu cực ảnh hưởng pin.
Odex
Firmware stock trên Android gần như luôn odex. Nghĩa là bên cạnh package chuẩn APK trong /system/app/ và /system/priv-app/, có file cùng tên với đuôi .odex. File odex chứa bytecode tối ưu đã qua validator và optimizer VM, ghi vào file riêng bằng tool như dexopt.
File odex nhằm offload VM và tăng tốc khởi chạy app odexed - mặt trái, ODEX ngăn sửa đổi firmware, gây vấn đề khi cập nhật, nên nhiều custom ROM như LineageOS phân phối không có ODEX.
Tạo file ODEX có nhiều cách (như Odexer Tool) - vấn đề là nó chỉ là hiệu ứng placebo. Khi Android hiện đại không tìm thấy file odex trong /system, hệ thống sẽ tự tạo và đặt vào /system/dalvik-cache/. Chính điều này xảy ra khi bạn flash Android mới và thấy thông báo "Busy, Optimizing Applications" một lúc.
Tweak Lowmemorykiller
Multitasking Android khác OS di động khác ở chỗ nó dựa trên mô hình kinh điển: app chạy ngầm, không giới hạn số app background (trừ khi set trong Developer Options, nhưng thường khuyên không nên) - chức năng chuyển background không bị dừng, dù hệ thống có quyền kill background app khi thiếu RAM (xem phần lowmemorykiller và OOM killer trước).
Quay lại cơ chế lowmemorykiller, Android hoạt động với RAM hạn chế và không có swap partition. User tiếp tục mở app, chuyển đổi, hệ thống im lặng kill background app không dùng để giải phóng RAM cho task chính.
Điều này rất hữu ích thời Android sơ khai, nhưng vì sao lại phổ biến dưới dạng app task-killer, thường hại hơn lợi? Task-killer app hoặc đánh thức theo khoảng thời gian, hoặc do user chạy, giải phóng RAM lớn, được coi là tích cực - RAM trống nhiều hơn nghĩa là thiết bị nhanh hơn, đúng không? Không hẳn vậy với Android.
Thực tế, RAM trống lớn thực sự có hại cho hiệu năng và pin. Khi app lưu trong RAM Android, dễ dàng gọi lên, khởi chạy. Hệ thống không cần dành nhiều tài nguyên chuyển app, vì nó đã có trong bộ nhớ.
Bởi vậy, task-killer không còn phổ biến như trước, nhưng người mới Android vẫn dùng (thiếu thông tin). Rất tiếc, xu hướng mới thay thế task-killer là tinh chỉnh cơ chế lowmemorykiller. Ví dụ app MinFreeManager, ý tưởng chính là tăng ngưỡng RAM trước khi hệ thống bắt đầu kill background app.
Ví dụ: RAM tiêu chuẩn hoạt động ở ngưỡng 4, 8, 12, 24, 32, 40 MB. Khi không gian trống 40MB bị lấp, một cached app (đã load vào RAM nhưng không chạy) sẽ bị kill. Android luôn giữ ít nhất 40MB RAM trống, đủ cho thêm một app trước khi LMK dọn dẹp - Android luôn cố gắng dùng tối đa RAM khả dụng mà không can thiệp trải nghiệm.
Rất tiếc, một số fan hâm mộ khuyến nghị tăng giá trị lên 100MB trước khi LMK kích hoạt. Bây giờ user mất RAM (100-40=60), thay vì dùng không gian này lưu background app, hệ thống giữ RAM trống vô ích.
Tuning LKM có thể hữu ích cho thiết bị cũ 512MB RAM, nhưng ai còn dùng nữa? 2GB là "tầm trung" hiện đại, 4GB là "tầm trung cao", nên LMK tweak thực sự lỗi thời và vô dụng.
I/O Tweaks
Trong nhiều script tối ưu Android thường thấy tweak subsystem I/O. Ví dụ script ThunderBolt! có các dòng:
echo 0 > $i/queue/rotational; echo 1024 > $i/queue/nr_requests;
Dòng đầu hướng dẫn I/O scheduler xử lý như SSD, dòng thứ hai tăng kích thước queue I/O tối đa từ 128 lên 1024 - vì biến $i chứa đường dẫn đến cây block device trong /sys, script chạy trong loop.
Tiếp theo là dòng liên quan scheduler CFQ:
echo 1 > $i/queue/iosched/back_seek_penalty; echo 1 > $i/queue/iosched/low_latency; echo 1 > $i/queue/iosched/slice_idle;
Sau đó là các dòng cho planner khác, nhưng hai lệnh đầu vô nghĩa vì:
- Kernel Linux hiện đại tự hiểu loại storage medium nó làm việc mặc định.
- Queue I/O dài (như 1024) vô nghĩa trên Android hiện đại, thậm chí trên desktop cũng vô nghĩa - chỉ khuyến nghị cho server nặng. Điện thoại của bạn không phải server Linux nặng.
Đối với Android, gần như không có app ưu tiên trong I/O và không có driver cơ học, nên planner tốt nhất là noop / FIFO-queue, kiểu scheduler "tweak" này không làm gì đặc biệt cho I/O subsystem. Thực tế, tất cả lệnh multi-screen đó tốt hơn thay bằng vòng lặp đơn giản:
for i in /sys/block/mmc*; do echo noop > $i/queue/scheduler; echo 0 > $i/queue/iostats; done
Điều này bật scheduler noop cho tất cả drive từ tích lũy thống kê I/O, có tác động tích cực nhưng rất nhỏ, gần như không đáng kể.
Tweak I/O vô nghĩa khác thường thấy: tăng read-ahead cho SD card lên 2MB. Read-ahead đọc trước dữ liệu từ media trước khi app yêu cầu. Kernel đoán dữ liệu cần thiết tương lai, pre-load vào RAM, giảm thời gian trả về. Nghe hay trên giấy, nhưng thuật toán read-ahead thường sai, dẫn đến hoạt động I/O không cần thiết, không kể tiêu thụ RAM cao.
Giá trị read-ahead 1-8MB khuyến nghị cho RAID-array, nhưng Android tốt nhất để mặc định 128KB.
Tweak hệ thống quản lý ảo (Virtual Memory Management)
Kỹ thuật "tối ưu" phổ biến khác là tinh chỉnh subsystem virtual memory management. Thường chỉ nhắm 2 biến kernel: vm.dirty_background_ratio và vm.dirty_ratio, điều chỉnh kích thước buffer lưu dữ liệu "dirty". Dirty data là dữ liệu đã ghi lên disk nhưng vẫn còn trong RAM chờ ghi.
Giá trị tweak điển hình trên Linux distro và Android:
vm.dirty_background_ratio = 10 vm.dirty_ratio = 20
Ý nghĩa: khi buffer dirty data đạt 10% tổng RAM, đánh thức luồng pdflush ghi dữ liệu lên disk - nếu ghi quá mạnh, buffer tiếp tục tăng, khi đạt 20% RAM, hệ thống chuyển sang ghi đồng bộ (không pre-buffer) - app ghi bị chặn cho đến khi ghi xong (AKA 'lag').
Cần hiểu: ngay khi buffer không đạt 10%, hệ thống tự kích hoạt pdflush sau 30 giây. Tổ hợp 10/20 hợp lý, ví dụ thiết bị 1GB RAM = 100/200MB RAM, đủ cho burst ghi tốc độ thường dưới tốc độ ghi NAND/SD (như cài app, copy file từ PC).
Vì lý do nào đó, tác giả script cố đẩy giá trị cao hơn, mức vô lý. Ví dụ script Xplix có tỷ lệ 50/90:
sysctl -w vm.dirty_background_ratio=50 sysctl -w vm.dirty_ratio=90
Trên thiết bị 1GB RAM, giới hạn dirty buffer 500/900MB, hoàn toàn vô ích cho Android, chỉ hoạt động dưới ghi liên tục lên disk - chỉ xảy ra trên server Linux nặng.
Script ThunderBolt! dùng giá trị hợp lý hơn, nhưng tổng thể vẫn vô nghĩa:
if [ "$mem" -lt 524288 ];then sysctl -w vm.dirty_background_ratio=15; sysctl -w vm.dirty_ratio=30; elif [ "$mem" -lt 1049776 ];then sysctl -w vm.dirty_background_ratio=10; sysctl -w vm.dirty_ratio=20; else sysctl -w vm.dirty_background_ratio=5; sysctl -w vm.dirty_ratio=10; fi;
Hai lệnh đầu cho smartphone 512MB RAM, lệnh thứ hai cho 1GB, các lệnh khác cho >1GB. Thực tế chỉ có một lý do thay đổi cài đặt mặc định - thiết bị có bộ nhớ nội bộ hoặc thẻ nhớ rất chậm. Trong trường hợp này, hợp lý giãn giá trị biến, ví dụ:
sysctl -w vm.dirty_background_ratio=10 sysctl -w vm.dirty_ratio=60
Khi bùng nổ ghi hệ thống, không phải ghi disk ngay, đến cuối mới chuyển sang chế độ đồng bộ, giảm lag khi ghi.
Các Tweak và Performance Tuning Vô Ích Khác
Còn nhiều "tối ưu hóa" khác thực sự không làm gì. Phần lớn không có tác dụng, một số cải thiện một khía cạnh nhưng làm giảm thiết备 ở khía cạnh khác (thường là hiệu năng vs hao pin).
Một số tối ưu phổ biến có thể hữu ích hoặc không, tùy hệ thống Android và thiết bị:
- Overclocking - tăng hiệu năng nhỏ, undervolting - tiết kiệm pin một chút.
- Database Optimization - lý thuyết nên cải thiện hiệu năng, nhưng đáng ngờ.
- Zipalign - ngược lại, tính năng built-in Android SDK căn chỉnh nội dung trong APK, nhưng trên store nhiều phần mềm không qua zipalign.
- Tắt dịch vụ hệ thống không cần thiết, gỡ app hệ thống và app thứ ba hiếm dùng. Cơ bản là gỡ bloatware.
- Custom kernel tối ưu cho thiết bị cụ thể (lại nói, không phải kernel nào cũng tốt).
- I/O scheduler noop đã mô tả.
- Thuật toán bão hòa TCP Westwood - hiệu quả hơn Cubic mặc định Android cho mạng không dây, có trong custom kernel.
Cài đặt build.prop Vô Dụng
LaraCraft304 từ diễn đàn XDA Developers đã nghiên cứu và tìm ra số lượng ấn tượng các cài đặt /system/build.prop được khuyến nghị bởi "chuyên gia" không tồn tại trong AOSP và CyanogenMod source. Danh sách:
ro.ril.disable.power.collapse ro.mot.eri.losalert.delay ro.config.hw_fast_dormancy ro.config.hw_power_saving windowsmgr.max_events_per_sec persist.cust.tel.eons ro.max.fling_velocity ro.min.fling_velocity ro.kernel.checkjni dalvik.vm.verify-bytecode debug.performance.tuning video.accelerate.hw ro.media.dec.jpeg.memcap ro.config.nocheckin profiler.force_disable_ulog profiler.force_disable_err_rpt ersist.sys.shutdown.mode ro.HOME_APP_ADJ