Trochę o zarządzaniu pamięcią w Androidzie - jak ją dostosować pod siebie.
Cytat:
Here the long story:
I just was curious if already someone tried to play around with Android's internal low-memory task killer.
We all know that Android uses a different way of handling processes. Instead of killing every process after its Activity ended, processes are kept until the system needs more memory. These processes usually should not harm the overall performance and should give speed improvements if you start an Activity again. That's the idea.
But when does Android kill a process? And which process? As far as I understood android keeps a LRU (last recently used) list and starts killing the oldest unneeded process. This way it is much smarter than any of the taskkillers we see in the Market.
Just for curiosity I started to investigate how this mechanism works. Please correct me if you think that I got something wrong:
What I found out:
ActivityManagerService.java tracks the "importance" of processes (is foreground, is running a service, ..) and reflects this importance by setting the "oom_adj" value of the process.
(For info: "oom_adj" is a value of every process under Linux which gives the kernel a hint, which process it can kill in an oom [out of memory] situation. You can see this value on every Linux 2.6 system in the proc directory: /proc/[PID]/oom_adj ). The higher this value is set, the more likely this process gets selected by the kernel's oom killer.)
It seems that on Android the current forefround application gets an oom_adj value of 0 and as soon it's not visible anymore it gets some higher value. I assume the concrete value is dependent by the processes' place in the LRU list.
The out-of-memory killer in the standard Linux kernel only runs in one situation: when the available memory is critical low. However in the Android Linux kernel there is implemented a more fine-grained handling of low memory situations.
I found the kernel source file "lowmemorykiller.c" (located in the kernel source tree under "drivers/misc/"; or look here for GIT source tree: http://tinyurl.com/lowmemkiller).
This module seems to be more configurable than the kernel's standard out-of-memory killer as you can define more than one memory limit, when it should get active and you can tell it which oom_adj values it may kill.
In other words:
You can say "if free memory goes below XXXX then kill some process with oom_adj greater then YYY; if free memory goes even more below than ZZZ then start to kill some processes with oom_adj greater than XYXY. and so on.."
So it's possible to define multiple memory criterias and matching processes which can be killed in these situations. Android seems to group running processes into 6 different categories (comments taken out of "ActivityManagerServer.java"):
Code:
FOREGROUND_APP:
// This is the process running the current foreground app. We'd really
// rather not kill it! Value set in system/rootdir/init.rc on startup.
VISIBLE_APP:
// This is a process only hosting activities that are visible to the
// user, so we'd prefer they don't disappear. Value set in
// system/rootdir/init.rc on startup.
SECONDARY_SERVER:
// This is a process holding a secondary server -- killing it will not
// have much of an impact as far as the user is concerned. Value set in
// system/rootdir/init.rc on startup.
HIDDEN_APP:
// This is a process only hosting activities that are not visible,
// so it can be killed without any disruption. Value set in
// system/rootdir/init.rc on startup.
CONTENT_PROVIDER:
// This is a process with a content provider that does not have any clients
// attached to it. If it did have any clients, its adjustment would be the
// one for the highest-priority of those processes.
EMPTY_APP:
// This is a process without anything currently running in it. Definitely
// the first to go! Value set in system/rootdir/init.rc on startup.
// This value is initalized in the constructor, careful when refering to
// this static variable externally.These 6 categories are reflected by 6 memory limits which are configured for the lowmemorykiller in the kernel.
Fortunately, it is possible to configure the lowmemorykiller at runtime! http://forum.xda-developers.com/imag...lies/smile.gif
(But only if you are root). The configuration is set in the file: "/sys/module/lowmemorykiller/parameters/minfree"
So if you want to see the current settings, you can do:
Code:
# cat /sys/module/lowmemorykiller/parameters/minfree
This should produce output like this (or similiar):
Code:
1536,2048,4096,5120,5632,6144
|
Czyli podsumowując - można ustawić samemu progi przy jakich Android będzie zwalniał pamięć ;)
http://forum.xda-developers.com/showthread.php?t=622666
Power of OpenSource! :)
U siebie w kernelu (dodaje fajne modyfikacje :)) mogę to regulować skryptem z /etc/init.d - nie trzeba używać aplikacji w stylu Kernel Tuner, która jest swoją drogą świetna ;)
Cytat:
# Config Minfree (a.k.a OOM or LMK value - in megabytes)
# 1 = Very Light (2,4,5,8,12)
# 2 = Light (4,8,10,16,24,32)
# 3 = Medium (4,8,16,32,48,64)
# 4 = Aggressive (8,16,32,64,96,128)
# 5 = Optimal I (8,16,32,64,150,180)
# 6 = Optimal II (8,16,32,64,180,200)
# 7 = Very Aggressive (16,32,64,128,192,256)
FREE=2;
|
Część skryptu, która to zmienia wygląda tak:
Cytat:
# Config Minfree
echo "0,1,2,4,6,15" > /sys/module/lowmemorykiller/parameters/adj
chmod 664 /sys/module/lowmemorykiller/parameters/minfree
if [ "$FREE" = "1" ]
then
echo "512,1024,1280,2048,3072,4096" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "2" ]
then
echo "1024,2048,2560,4096,6144,8192" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "3" ]
then
echo "1024,2048,4096,8192,12288,16384" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "4" ]
then
echo "2048,4096,8192,16384,24576,32768" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "5" ]
then
echo "2048,4096,8192,16384,38400,46080" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "6" ]
then
echo "2048,4096,8192,24576,46080,51200" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "7" ]
then
echo "4096,8192,16384,32768,49152,65536" > /sys/module/lowmemorykiller/parameters/minfree
fi
|
Cały mod prezentuje się tak:
Kod:
#!/system/bin/sh
# ==============================
# AIO kernel MOD
# ==============================
# Script base created by IBA21
# ==============================
# Modified by axetilen
# ==============================
#### Change your own settings here!!!
### General arena: customize settings for 3 kernels
### NOT ALL SETTINGS ARE FOR ALL KERNELS !!!
# Config 3D GPU clock
# 266667000 = 267mhz
# 300000000 = 300mhz
# 320000000 = 320mhz
GPU=300000000;
# Config i/o scheduler
# deadline
# cfq
# noop
# sio
# vr
IO=sio;
# Vsync Control
# 0 = Vsync disabled
# 1 = Vsync enabled
VSYNC=1;
# Disable logcat
# 1 = yes
# 2 = no
LOGCAT=2;
# Enable Sweep2Wake - Only for PYD & Sultan kernels
# 0 = disabled
# 1 = enabled
# 2 = enabled (with no button backlight)
SWEEP=2;
# Enable Fastcharge - Only for PYD & Sultan kernels
# 0 = disabled
# 1 = substitute AC to USB charging always
# 2 = substitute AC to USB charging only if there is no USB peripheral detected
FASTCHARGE=0;
# Fsync Control - Only for PYD & Sultan kernels
# 2 = Fsync disabled
# 1 = Fsync enabled
FSYNC=2;
## Config CPU Frequency
# Config CPU max frequency
MAXFREQ=1242000;
# Config CPU max frequency for EACH core
MAX0=;
MAX1=;
# Config CPU min frequency for BOTH cores
MINFREQ=192000;
# Config CPU max screen-off frequency - Only for PYD kernel
MAXOFF=648000;
# Config CPU phase frequencies
# Second phase frequency
PHASE=972000;
# Third phase frequency (only for badass governor - Sultan kernel)
PHASE3=;
# Config OnDemand
# 1 = battery save (sampling rate = 1.2 second)
# 2 = balance (sampling rate = 0.5 second)
# 3 = performance (sampling rate = 0.1 second)
OND=;
# Config Minfree (a.k.a OOM or LMK value - in megabytes)
# 1 = Very Light (2,4,5,8,12)
# 2 = Light (4,8,10,16,24,32)
# 3 = Medium (4,8,16,32,48,64)
# 4 = Aggressive (8,16,32,64,96,128)
# 5 = Optimal I (8,16,32,64,150,180)
# 6 = Optimal II (8,16,32,64,180,200)
# 7 = Very Aggressive (16,32,64,128,192,256)
FREE=2;
# Notification LED Duration Mod (Yank555)
# 0 = Will blink forever until cleared by user
# 1 = Will blink as requested by app or until cleared by user
# 2 = Will blink TWICE as requested by app multiplied by value or until cleared by user
# 5 = Will blink 5 TIMES as requested by app multiplied by value or until cleared by user
# 10 = Will blink 10 TIMES as requested by app or until cleared by user
# 60 = Will blink 60 TIMES as requested by app or until cleared by user
# 255 = Will blink 255 TIMES as requested by app multiplied by value or until cleared by user
LED=1;
# Config CPU governor
# badass
# intellidemand
# ondemand
# lagfree
# performance
GOV=lagfree;
# Config 2D GPU clock
# 200000000 = 200mhz
# 228571000 = 228mhz (229mhz)
# 266667000 = 267mhz
DD=228571000;
# Kernel Based msm_mpdecision (Show-p1984)
# 1 = enabled
# 0 = disable mpdecision and force both CPU cores online
MSM=1;
# Kernel samepage merging (KSM)
# 0 = disabled
# 1 = enabled
KSM=0;
# Config badass
# 1 = battery save
# 2 = balance
# 3 = performance
BAD=;
## Config intellidemand
# Inactive max frequency
INTELLIDEMAND=;
####### This is the end of the area that you can config #######
### Fobidden area - PlEASE DO NOT CHANGE ANYTHING FROM THIS
## Config CPU governor
echo "$GOV" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo "$GOV" > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
# Config OnDemand
if [ "$GOV" = "ondemand" ]
then
if [ "$OND" = "1" ]
then
echo 120000 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
fi
if [ "$OND" = "2" ]
then
echo 50000 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
fi
if [ "$OND" = "3" ]
then
echo 10000 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
fi
fi
# Config badass
if [ "$GOV" = "badass" ]
then
if [ "$BAD" = "1" ]
then
echo 50000 > /sys/devices/system/cpu/cpufreq/badass/sampling_rate
echo 140 > /sys/devices/system/cpu/cpufreq/badass/busy_threshold
echo 110 > /sys/devices/system/cpu/cpufreq/badass/busy_clr_threshold
echo 80 > /sys/devices/system/cpu/cpufreq/badass/semi_busy_threshold
echo 20 > /sys/devices/system/cpu/cpufreq/badass/semi_busy_clr_threshold
echo 300 > /sys/devices/system/cpu/cpufreq/badass/gpu_semi_busy_threshold
echo 250 > /sys/devices/system/cpu/cpufreq/badass/gpu_semi_busy_clr_threshold
echo 750 > /sys/devices/system/cpu/cpufreq/badass/gpu_busy_threshold
echo 600 > /sys/devices/system/cpu/cpufreq/badass/gpu_busy_clr_threshold
fi
if [ "$BAD" = "2" ]
then
echo 50000 > /sys/devices/system/cpu/cpufreq/badass/sampling_rate
echo 130 > /sys/devices/system/cpu/cpufreq/badass/busy_threshold
echo 100 > /sys/devices/system/cpu/cpufreq/badass/busy_clr_threshold
echo 14 > /sys/devices/system/cpu/cpufreq/badass/semi_busy_threshold
echo 6 > /sys/devices/system/cpu/cpufreq/badass/semi_busy_clr_threshold
echo 260 > /sys/devices/system/cpu/cpufreq/badass/gpu_semi_busy_threshold
echo 180 > /sys/devices/system/cpu/cpufreq/badass/gpu_semi_busy_clr_threshold
echo 700 > /sys/devices/system/cpu/cpufreq/badass/gpu_busy_threshold
echo 500 > /sys/devices/system/cpu/cpufreq/badass/gpu_busy_clr_threshold
fi
if [ "$BAD" = "3" ]
then
echo 10000 > /sys/devices/system/cpu/cpufreq/badass/sampling_rate
echo 120 > /sys/devices/system/cpu/cpufreq/badass/busy_threshold
echo 80 > /sys/devices/system/cpu/cpufreq/badass/busy_clr_threshold
echo 8 > /sys/devices/system/cpu/cpufreq/badass/semi_busy_threshold
echo 4 > /sys/devices/system/cpu/cpufreq/badass/semi_busy_clr_threshold
echo 150 > /sys/devices/system/cpu/cpufreq/badass/gpu_semi_busy_threshold
echo 50 > /sys/devices/system/cpu/cpufreq/badass/gpu_semi_busy_clr_threshold
echo 300 > /sys/devices/system/cpu/cpufreq/badass/gpu_busy_clr_threshold
echo 450 > /sys/devices/system/cpu/cpufreq/badass/gpu_busy_threshold
fi
fi
# Config intellidemand
if [ "$GOV" = "intellidemand" ]
then
echo 1 > /sys/devices/system/cpu/cpufreq/intellidemand/io_is_busy
echo $MAXFREQ > /sys/devices/system/cpu/cpufreq/intellidemand/lmf_active_max_freq
echo $MAX0 > /sys/devices/system/cpu/cpufreq/intellidemand/lmf_active_max_freq
echo $INTELLIDEMAND > /sys/devices/system/cpu/cpufreq/intellidemand/lmf_inactive_max_freq
fi
# Config CPU Frequency
chmod 644 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
echo $MAXFREQ > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
chmod 644 /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
echo $MINFREQ > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
chmod 644 /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq
echo $MAXFREQ > /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq
chmod 644 /sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq
echo $MINFREQ > /sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq
echo $MAX0 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
echo $MAX1 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq
chmod 644 /sys/devices/system/cpu/cpu0/cpufreq/screen_off_max_freq
echo $MAXOFF > /sys/devices/system/cpu/cpu0/cpufreq/screen_off_max_freq
# Config Second Phase Frequency
chmod 644 /sys/devices/system/cpu/cpufreq/ondemand/two_phase_freq
echo $PHASE > /sys/devices/system/cpu/cpufreq/ondemand/two_phase_freq
if [ "$GOV" = "badass" ]
then
chmod 644 /sys/devices/system/cpu/cpufreq/badass/two_phase_freq
echo $PHASE > /sys/devices/system/cpu/cpufreq/badass/two_phase_freq
fi
if [ "$GOV" = "intellidemand" ]
then
chmod 644 /sys/devices/system/cpu/cpufreq/intellidemand/two_phase_freq
echo $PHASE > /sys/devices/system/cpu/cpufreq/intellidemand/two_phase_freq
fi
# Config Three Phase Frequency
if [ "$GOV" = "badass" ]
then
chmod 644 /sys/devices/system/cpu/cpufreq/badass/three_phase_freq
echo $PHASE3 > /sys/devices/system/cpu/cpufreq/badass/three_phase_freq
fi
# Config 3D GPU setting
chmod 644 /sys/devices/platform/kgsl-3d0.0/kgsl/kgsl-3d0/max_gpuclk
echo $GPU > /sys/devices/platform/kgsl-3d0.0/kgsl/kgsl-3d0/max_gpuclk
# Config 2D GPU setting
chmod 644 /sys/devices/platform/kgsl-2d0.0/kgsl/kgsl-2d0/max_gpuclk
chmod 644 /sys/devices/platform/kgsl-2d0.0/kgsl/kgsl-2d0/gpuclk
chmod 644 /sys/devices/platform/kgsl-2d1.1/kgsl/kgsl-2d1/max_gpuclk
chmod 644 /sys/devices/platform/kgsl-2d1.1/kgsl/kgsl-2d1/gpuclk
echo $DD > /sys/devices/platform/kgsl-2d0.0/kgsl/kgsl-2d0/max_gpuclk
echo $DD > /sys/devices/platform/kgsl-2d0.0/kgsl/kgsl-2d0/gpuclk
echo $DD > /sys/devices/platform/kgsl-2d1.1/kgsl/kgsl-2d1/max_gpuclk
echo $DD > /sys/devices/platform/kgsl-2d1.1/kgsl/kgsl-2d1/gpuclk
# Config Sweep2Wake
chmod 644 /sys/android_touch/sweep2wake
echo "$SWEEP" > /sys/android_touch/sweep2wake
# Config Notification LED Time-out
chmod 644 sys/kernel/notification_leds/off_timer_multiplier
echo "$LED" > /sys/kernel/notification_leds/off_timer_multiplier
chmod 644 /sys/kernel/fast_charge/force_fast_charge
echo "$FASTCHARGE" > /sys/kernel/fast_charge/force_fast_charge
chmod 644 sys/kernel/notification_leds/off_timer_multiplier
echo "$LED" > /sys/kernel/notification_leds/off_timer_multiplier
# Config msm_decision
if [ "$MSM" = "1" ]
then
chmod 777 /sys/kernel/msm_mpdecision/conf/enabled
echo "$MSM" > /sys/kernel/msm_mpdecision/conf/enabled
chmod 777 /sys/devices/system/cpu/cpu1/online
fi
if [ "$MSM" = "0" ]
then
chmod 777 /sys/kernel/msm_mpdecision/conf/enabled
echo "$MSM" > /sys/kernel/msm_mpdecision/conf/enabled
chmod 777 /sys/devices/system/cpu/cpu1/online
echo "1" > /sys/devices/system/cpu/cpu1/online
chmod 444 /sys/devices/system/cpu/cpu1/online
fi
chmod 777 /system/bin/mpdecision
rm -f /system/bin/mpdecision
chmod 777 /system/bin/thermald
rm -f /system/bin/thermald
chmod 777 /system/etc/thermald.conf
rm -f /system/etc/thermald.conf
chmod 777 /system/etc/init.post_boot.sh
rm -f /system/etc/init.post_boot.sh
chmod 777 /system/etc/init.qcom.post_boot.sh
rm -f /system/etc/init.qcom.post_boot.sh
# Config KSM
chmod 644 /sys/kernel/mm/ksm/run
echo "$KSM" > /sys/kernel/mm/ksm/run
# Config i/o scheduler
chmod 644 /sys/block/mmcblk0/queue/scheduler
echo "$IO" > /sys/block/mmcblk0/queue/scheduler
chmod 644 /sys/block/mmcblk1/queue/scheduler
echo "$IO" > /sys/block/mmcblk1/queue/scheduler
# Config Minfree
echo "0,1,2,4,6,15" > /sys/module/lowmemorykiller/parameters/adj
chmod 664 /sys/module/lowmemorykiller/parameters/minfree
if [ "$FREE" = "1" ]
then
echo "512,1024,1280,2048,3072,4096" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "2" ]
then
echo "1024,2048,2560,4096,6144,8192" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "3" ]
then
echo "1024,2048,4096,8192,12288,16384" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "4" ]
then
echo "2048,4096,8192,16384,24576,32768" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "5" ]
then
echo "2048,4096,8192,16384,38400,46080" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "6" ]
then
echo "2048,4096,8192,24576,46080,51200" > /sys/module/lowmemorykiller/parameters/minfree
fi
if [ "$FREE" = "7" ]
then
echo "4096,8192,16384,32768,49152,65536" > /sys/module/lowmemorykiller/parameters/minfree
fi
# Config logcat
if [ "$LOGCAT" = "1" ]
then
if [ -e /dev/log/main ] ; then
rm /dev/log/main
fi
fi
# Config Vsync
if [ "$VSYNC" = "1" ]
then
mount -t debugfs debugfs /sys/kernel/debug
echo "1" > /sys/kernel/debug/msm_fb/0/vsync_enable
echo "1" > /sys/kernel/debug/msm_fb/0/hw_vsync_mode
umount /sys/kernel/debug
fi
if [ "$VSYNC" = "2" ]
then
mount -t debugfs debugfs /sys/kernel/debug
echo "0" > /sys/kernel/debug/msm_fb/0/vsync_enable
echo "0" > /sys/kernel/debug/msm_fb/0/hw_vsync_mode
umount /sys/kernel/debug
fi
# Config Fsync
if [ "$FSYNC" = "2" ]
then
echo "0" > sys/class/misc/fsynccontrol/fsync_enabled
fi
|