Skip to content

Commit

Permalink
v6 (20200228)
Browse files Browse the repository at this point in the history
新增:1/2GB物理内存的参数配置
新增:adjshield和fscache-ctrl使用armv7a-linux-androideabi21-clang编译,兼容32位平台
新增:禁用高通在中低端平台使用的per-process-reclaim,它的回收可能偏激进
新增:添加Adjshield的SELinux规则,由Magisk提供支持
新增:迁移到Magisk 20.3模板,向下兼容到19.0
修复:加大获取FSCC固定缓存大小的延时,修复未等待FSCC加载完毕就读取的值偏小
修复:ps/swapon/swapoff参数在BusyBox v1.31.1的兼容性,优先使用Magisk的BusyBox,/system/bin兼容性差异性太大
修复:动态获取MODULE_PATH,不再使用hardcore值,改进在低Magisk版本的兼容性
改进:完善关闭一加memory_plus,无需用户关闭“RamBoost启动加速”
改进:回滚使用巨大的shrinker调用间隔,据测试似乎有助于改进流畅度和zram利用率
改进:去掉adj档位设置,新老平台采用的adj档位完全不同
改进:调高efk并对内核内存回收线程设置高CFS优先级代替prefer_idle,改进在新老平台的表现一致性
改进:增加mem_opt_main.sh可重入性
改进:同步libcommon更新
改进:移除libpowercfg.sh

Signed-off-by: Matt Yang <yccy@outlook.com>
  • Loading branch information
yc9559 committed Feb 28, 2020
1 parent 9909705 commit 2db0e82
Show file tree
Hide file tree
Showing 20 changed files with 406 additions and 467 deletions.
180 changes: 101 additions & 79 deletions META-INF/com/google/android/update-binary
Original file line number Diff line number Diff line change
@@ -1,46 +1,59 @@
#!/sbin/sh

TMPDIR=/dev/tmp
MOUNTPATH=/dev/magisk_img
#################
# Initialization
#################

# Default permissions
umask 022

# Initial cleanup
# Global vars
TMPDIR=/dev/tmp
PERSISTDIR=/sbin/.magisk/mirror/persist

rm -rf $TMPDIR 2>/dev/null
mkdir -p $TMPDIR

# echo before loading util_functions
ui_print() { echo "$1"; }

require_new_magisk() {
ui_print "***********************************"
ui_print " Please install the latest Magisk! "
ui_print "***********************************"
ui_print "*******************************"
ui_print " Please install Magisk v19.0+! "
ui_print "*******************************"
exit 1
}

imageless_magisk() {
[ $MAGISK_VER_CODE -gt 18100 ]
is_legacy_script() {
unzip -l "$ZIPFILE" install.sh | grep -q install.sh
return $?
}

##########################################################################################
print_modname() {
local len
len=`echo -n $MODNAME | wc -c`
len=$((len + 2))
local pounds=`printf "%${len}s" | tr ' ' '*'`
ui_print "$pounds"
ui_print " $MODNAME "
ui_print "$pounds"
ui_print "*******************"
ui_print " Powered by Magisk "
ui_print "*******************"
}

##############
# Environment
##########################################################################################
##############

OUTFD=$2
ZIPFILE=$3

mount /data 2>/dev/null

# Load utility functions
if [ -f /data/adb/magisk/util_functions.sh ]; then
. /data/adb/magisk/util_functions.sh
NVBASE=/data/adb
else
require_new_magisk
fi
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
. /data/adb/magisk/util_functions.sh
[ $MAGISK_VER_CODE -gt 18100 ] || require_new_magisk

# Preperation for flashable zips
setup_flashable
Expand All @@ -54,98 +67,107 @@ api_level_arch_detect
# Setup busybox and binaries
$BOOTMODE && boot_actions || recovery_actions

##########################################################################################
##############
# Preparation
##########################################################################################

# Extract common files
unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2

[ ! -f $TMPDIR/install.sh ] && abort "! Unable to extract zip file!"
# Load install script
. $TMPDIR/install.sh
##############

if imageless_magisk; then
$BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules
MODULEROOT=$NVBASE/$MODDIRNAME
else
$BOOTMODE && IMGNAME=magisk_merge.img || IMGNAME=magisk.img
IMG=$NVBASE/$IMGNAME
request_zip_size_check "$ZIPFILE"
mount_magisk_img
MODULEROOT=$MOUNTPATH
fi
# Extract prop file
unzip -o "$ZIPFILE" module.prop -d $TMPDIR >&2
[ ! -f $TMPDIR/module.prop ] && abort "! Unable to extract zip file!"

$BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules
MODULEROOT=$NVBASE/$MODDIRNAME
MODID=`grep_prop id $TMPDIR/module.prop`
MODPATH=$MODULEROOT/$MODID

print_modname

ui_print "******************************"
ui_print "Powered by Magisk (@topjohnwu)"
ui_print "******************************"

##########################################################################################
# Install
##########################################################################################
MODNAME=`grep_prop name $TMPDIR/module.prop`

# Create mod paths
rm -rf $MODPATH 2>/dev/null
mkdir -p $MODPATH

on_install
##########
# Install
##########

if is_legacy_script; then
unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2

# Load install script
. $TMPDIR/install.sh

# Remove placeholder
rm -f $MODPATH/system/placeholder 2>/dev/null
# Callbacks
print_modname
on_install

# Custom uninstaller
[ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh
# Custom uninstaller
[ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh

# Auto Mount
if imageless_magisk; then
# Skip mount
$SKIPMOUNT && touch $MODPATH/skip_mount

# prop file
$PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop

# Module info
cp -af $TMPDIR/module.prop $MODPATH/module.prop

# post-fs-data scripts
$POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh

# service scripts
$LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh

ui_print "- Setting permissions"
set_permissions
else
$SKIPMOUNT || touch $MODPATH/auto_mount
fi
print_modname

# prop files
$PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop
unzip -o "$ZIPFILE" customize.sh -d $MODPATH >&2

# Module info
cp -af $TMPDIR/module.prop $MODPATH/module.prop
if $BOOTMODE; then
# Update info for Magisk Manager
if imageless_magisk; then
mktouch $NVBASE/modules/$MODID/update
cp -af $TMPDIR/module.prop $NVBASE/modules/$MODID/module.prop
else
mktouch /sbin/.magisk/img/$MODID/update
cp -af $TMPDIR/module.prop /sbin/.magisk/img/$MODID/module.prop
fi
fi
if ! grep -q '^SKIPUNZIP=1$' $MODPATH/customize.sh 2>/dev/null; then
ui_print "- Extracting module files"
unzip -o "$ZIPFILE" -x 'META-INF/*' -d $MODPATH >&2

# post-fs-data mode scripts
$POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh
# Default permissions
set_perm_recursive $MODPATH 0 0 0755 0644
fi

# service mode scripts
$LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh
# Load customization script
[ -f $MODPATH/customize.sh ] && . $MODPATH/customize.sh
fi

# Handle replace folders
for TARGET in $REPLACE; do
ui_print "- Replace target: $TARGET"
mktouch $MODPATH$TARGET/.replace
done

ui_print "- Setting permissions"
set_permissions
if $BOOTMODE; then
# Update info for Magisk Manager
mktouch $NVBASE/modules/$MODID/update
cp -af $MODPATH/module.prop $NVBASE/modules/$MODID/module.prop
fi

# Copy over custom sepolicy rules
if [ -f $MODPATH/sepolicy.rule -a -e $PERSISTDIR ]; then
ui_print "- Installing custom sepolicy patch"
PERSISTMOD=$PERSISTDIR/magisk/$MODID
mkdir -p $PERSISTMOD
cp -af $MODPATH/sepolicy.rule $PERSISTMOD/sepolicy.rule
fi

# Remove stuffs that don't belong to modules
rm -rf \
$MODPATH/system/placeholder $MODPATH/customize.sh \
$MODPATH/README.md $MODPATH/.git* 2>/dev/null

##########################################################################################
##############
# Finalizing
##########################################################################################
##############

cd /
imageless_magisk || unmount_magisk_img
$BOOTMODE || recovery_cleanup
rm -rf $TMPDIR $MOUNTPATH
rm -rf $TMPDIR

ui_print "- Done"
exit 0
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Memory management optimaization for Android arm64 platforms
# Memory management optimaization for Android platforms

## Feature

Expand Down Expand Up @@ -30,22 +30,23 @@ English version:

## Requirement

- Magisk >= 17.0
- ARM64
- ARM/ARM64
- Magisk >= 19.0
- Android 6.0+

## Installation

- 安装模块重启,打开`/sdcard/Android/panel_qti_mem.txt`修改想要的ZRAM大小和压缩算法,重启后生效
- Magisk >= 19.0
- 安装本模块重启,打开`/sdcard/Android/panel_qti_mem.txt`修改想要的ZRAM大小和压缩算法,重启后生效
- 打开`/sdcard/Android/panel_adjshield.txt`添加需要保持在后台的APP包名,重启后生效
- ZRAM大小默认值如下:
- 1-2GB内存默认开启0.5GB的ZRAM
- 3-4GB内存默认开启1GB的ZRAM
- 6GB内存默认开启2GB的ZRAM
- 8GB内存默认开启3GB的ZRAM
- 12GB内存默认开启0GB的ZRAM
- 一加用户需要关闭“RamBoost启动加速”/“SmartBoost启动加速”这个预读器
- 目前不支持ZSWAP
- 目前不支持用户态LMKD
- 目前不支持用户态LMK

## FAQ

Expand All @@ -55,7 +56,7 @@ Q: 这是什么,是一键全优化吗?
A: 这个是改善Android缓存进程管理的Magisk模块,避免过快地清除后台缓存进程并且改进低内存情况下的流畅度,不包含CPU调度优化之类的其他部分。

Q: 我的设备能够使用这个吗?
A: 本模块适用于Android版本不低于6.0的安卓64位平台,不局限于高通平台,也就是说基本从2016年开始上市的设备都可以使用
A: 本模块适用于Android版本>=6.0的安卓32/64位平台,不局限于高通平台。

Q: 不开启ZRAM是不是这个模块就没用了?
A: ZRAM控制只是本模块的一小部分功能,不开启ZRAM使用本模块也能够改进低内存情况下的流畅度。在panel文件的ZRAM项目显示`unsupported`仅表示内核不支持ZRAM,其他参数修改和缓存控制还是生效的。
Expand Down Expand Up @@ -84,7 +85,7 @@ Q: 将系统常用文件固定在文件页面缓存有什么用?
A: 在谷歌的[安卓性能调优文档](https://source.android.com/devices/tech/debug/jank_jitter#page-cache),提到了低内存情况下页面缓存出现颠簸是长卡顿的主要原因,它在实际中表现为返回桌面时出现100ms以上的停顿,在返回桌面手势动画中尤为明显。一般来说安卓框架的`PinnerService`已经把常用文件固定在内存中,但是某些平台的设备比如一加7Pro并没有这一服务,或者已固定在内存的覆盖范围不够大导致仍然出现关键页面缓存颠簸。此模块将绝大多数系统常用文件固定在文件页面缓存,弥补已有设置的不完善之处。

Q: 防止特定APP被安卓内核态LMK清除是如何做到的?
A: 即使调高LMK触发阈值以及加大SWAP空间,某些关键APP可能仍然无法一直在后台存活,更不用说在低于4GB物理内存的设备上想要同时保活大型游戏和常用聊天软件了。在以往的解决方法中,需要Xposed框架实现对指定APP的保活,但是Xposed框架某些人并不喜欢(比如我)。安卓系统框架自身或者通知用户态LMKD调用`procfs`接口更改APP的`oom_score_adj`,内核态LMK在页面缓存不足介入终止`oom_score_adj`最高的进程。本模块的`AdjShield`定期遍历`procfs`匹配需要保护的APP包名,拦截对它的`oom_score_adj`的写入操作,确保需要保护的APP不会是内核态LMK最先被终止的。受保护的APP的`oom_score_adj`被固定在0。定期遍历的间隔被设置在2分钟,每次遍历的耗时经过优化控制在40ms(Cortex-A55@0.8G)以内,几乎不会给续航和性能造成额外负担。
A: 即使调高LMK触发阈值以及加大SWAP空间,某些关键APP可能仍然无法一直在后台存活,更不用说在低于4GB物理内存的设备上想要同时保活大型游戏和常用聊天软件了。在以往的解决方法中,需要Xposed框架实现对指定APP的保活,但是Xposed框架某些人并不喜欢(比如我)。安卓系统框架自身或者通知用户态LMKD调用`procfs`接口更改APP的`oom_score_adj`,内核态LMK在页面缓存不足介入终止`oom_score_adj`最高的进程。本模块的`AdjShield`定期遍历`procfs`匹配需要保护的APP包名,拦截对它的`oom_score_adj`的写入操作,确保需要保护的APP不会是内核态LMK(也包含simpleLMK)最先被终止的。受保护的APP的`oom_score_adj`被固定在0。定期遍历的间隔被设置在2分钟,每次遍历的耗时经过优化控制在40ms(Cortex-A55@0.8G)以内,几乎不会给续航和性能造成额外负担。

Q: ZRAM和swap是什么关系?
A: ZRAM是swap分区的一种实现方式。在内核回收内存时,将非活动的匿名内存页换入块设备,被称为swap。这个块设备可以是独立的swap分区,可以是swapfile,也可以是ZRAM。ZRAM将换入的页面压缩后放到内存,所以相比传统的swap方式在读写延迟上低几个数量级,性能更好。
Expand All @@ -104,3 +105,6 @@ A: 把Magisk模块跟内核模块对比是不合适的,把SimpleLMK跟LMK对
@予你长情i--发现与蝰蛇杜比音效共存版magisk模块冲突导致panel读写错误
@choksta --协助诊断v4版FSCC固定过多文件到内存
@yishisanren --协助诊断v5版FSCC在三星平台固定过多文件到内存
@方块白菜 --协助调试在联发科X10平台ZRAM相关功能
@Simple9 --协助诊断在Magisk低于19.0的不兼容问题
@〇MH1031 --协助诊断位于/system/bin二进制工具集的不兼容问题
Binary file modified bin/adjshield
Binary file not shown.
Binary file modified bin/fscache-ctrl
Binary file not shown.
7 changes: 0 additions & 7 deletions common/service.sh

This file was deleted.

67 changes: 67 additions & 0 deletions customize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/sbin/sh

# If you need even more customization and prefer to
# do everything on your own, declare SKIPUNZIP=1
SKIPUNZIP=0

# List all directories you want to directly replace in the system
# Construct your list in the following format
# This is an example
# REPLACE_EXAMPLE="
# /system/app/Youtube
# /system/priv-app/SystemUI
# /system/framework
# "
REPLACE=""

# ! DO NOT use any Magisk internal paths as those are NOT public API.
# ! DO NOT use other functions in util_functions.sh as they are NOT public API.
# ! Non public APIs are not guranteed to maintain compatibility between releases.

# Available variables:
# MAGISK_VER (string): the version string of current installed Magisk
# MAGISK_VER_CODE (int): the version code of current installed Magisk
# BOOTMODE (bool): true if the module is currently installing in Magisk Manager
# MODPATH (path): the path where your module files should be installed
# TMPDIR (path): a place where you can temporarily store files
# ZIPFILE (path): your module's installation zip
# ARCH (string): the architecture of the device. Value is either arm, arm64, x86, or x64
# IS64BIT (bool): true if $ARCH is either arm64 or x64
# API (int): the API level (Android version) of the device

# Availible functions:
# ui_print <msg>
# print <msg> to console
# Avoid using 'echo' as it will not display in custom recovery's console
# abort <msg>
# print error message <msg> to console and terminate installation
# Avoid using 'exit' as it will skip the termination cleanup steps
# set_perm <platform_name> <owner> <group> <permission> [context]
# if [context] is not set, the default is "u:object_r:system_file:s0"
# this function is a shorthand for the following commands:
# chown owner.group platform_name
# chmod permission platform_name
# chcon context platform_name
# set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
# if [context] is not set, the default is "u:object_r:system_file:s0"
# for all files in <directory>, it will call:
# set_perm file owner group filepermission context
# for all directories in <directory> (including itself), it will call:
# set_perm dir owner group dirpermission context

ui_print ""
ui_print "* QTI memory optimization"
ui_print "* https://github.com/yc9559/qti-mem-opt"
ui_print "* Author: Matt Yang"
ui_print "* Version: v6 (20200228)"
ui_print ""

# Only some special files require specific permissions
# The default permissions should be good enough for most cases
# set_perm_recursive $MODPATH/system/lib 0 0 0755 0644
# set_perm $MODPATH/system/bin/app_process32 0 2000 0755 u:object_r:zygote_exec:s0
# set_perm $MODPATH/system/bin/dex2oat 0 2000 0755 u:object_r:dex2oat_exec:s0
# set_perm $MODPATH/system/lib/libart.so 0 0 0644

# set binaries executable
set_perm_recursive $MODPATH/bin 0 0 0755 0755
Loading

0 comments on commit 2db0e82

Please sign in to comment.