Skip to content

Commit

Permalink
Merge pull request #17 from alibaba/develop
Browse files Browse the repository at this point in the history
 Added support for ColorOS12
  • Loading branch information
zhi1ong authored Dec 22, 2021
2 parents 85e7dc3 + 82daeb7 commit 3a9535a
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 33 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
针对此问题,一般首先能想到的就是排查内存泄漏问题,但往往收效甚微,多半是因为随着业务的发展,确实是需要这么多虚拟内存。诚然通过升级64位架构可以把地址空间上限扩充到512GB,但是因为各种原因(包大小、维护成本等等),目前大部分应用尚未完成升级,所以在这里提供一种新的思路。

## 二、原理
通过一系列技术手段实现运行期间动态调整`Region Space`预分配的地址空间,释放出最多`900MB`(根据实际情况调整参数)虚拟内存给到 libc:malloc,增加了接近30%的地址上限,大幅度给应用续命。(细节待补充)
通过一系列技术手段实现运行期间动态调整`Region Space`预分配的地址空间,释放出最多`900MB`(根据实际情况调整参数)虚拟内存给到 libc:malloc,增加了接近30%的地址上限,大幅度给应用续命。

详细介绍:[阿里开源 Patrons:大型 32 位 Android 应用稳定性提升 50% 的“黑科技”](https://www.infoq.cn/article/bvbf3iwjztvem4szamvw)

## 三、使用方式
编译`patrons`模块 or 使用以下中心仓库的坐标,主工程依赖该模块产物,在合适的时机进行初始化:
Expand All @@ -24,7 +26,7 @@
mavenCentral()
}
dependencies {
implementation 'com.alibaba:patrons:1.0.6.4'
implementation 'com.alibaba:patrons:1.0.6.5'
}
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ ext {
ndkVersion = "20.1.5948944"
cmakeVersion = "3.10.2"
abiFilters = "armeabi-v7a"
versionName = "1.0.6.4"
versionName = "1.0.6.5"
}
2 changes: 1 addition & 1 deletion patrons/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ POM_NAME=Patrons SDK
POM_ARTIFACT_ID=patrons
POM_PACKAGING=aar
POM_DESCRIPTION=Patrons SDK for android.
VERSION_NAME=1.0.6.4
VERSION_NAME=1.0.6.5
53 changes: 31 additions & 22 deletions patrons/src/main/cpp/patrons_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ int NativeInit() {
__PATRONS_API_VERSION, api_level, debuggable, has_exception_handle_, heapsize);

LOGD("[device] brand = %s", brand);
LOGD("[device] system brand = %s", system_brand);
LOGD("[device] device = %s", device);
LOGD("[device] rom version = %s", rom_version);
LOGD("[device] fingerprint = %s", fingerprint);

// 判断 Android 版本
Expand Down Expand Up @@ -335,36 +337,43 @@ Java_com_alibaba_android_patronus__1Patrons_getCurrentRegionSpaceSize(__unused J
}

JNIEXPORT jstring JNICALL
Java_com_alibaba_android_patronus__1Patrons_dumpLogs(JNIEnv *env, jclass clazz, jboolean cleanAfterDump) {
Java_com_alibaba_android_patronus__1Patrons_dumpLogs(JNIEnv *env, jclass clazz,
jboolean cleanAfterDump) {
pthread_mutex_lock(&log_lock);

char current_cursor = dump_cursor;

if (current_cursor <= 0) {
return (*env)->NewStringUTF(env, "the native log buffer is empty");
}
jstring logs;

char *tmp = malloc(current_cursor * 256 * sizeof(char));
memset(tmp, 0, current_cursor * 256 * sizeof(char));
strcat(tmp, "\nPatrons Core Dump: ");
strcat(tmp, __PATRONS_API_VERSION);
strcat(tmp, "↵\n");

// 按行拼接日志
for (int i = 0; i < current_cursor; i++) {
if (dump_logs[i] != NULL) {
strcat(tmp, dump_logs[i]);
strcat(tmp, "↵\n");
if (current_cursor <= 0) {
logs = (*env)->NewStringUTF(env, "the native log buffer is empty");
} else {
char *tmp = malloc(current_cursor * 256 * sizeof(char));
memset(tmp, 0, current_cursor * 256 * sizeof(char));
strcat(tmp, "\nPatrons Core Dump: ");
strcat(tmp, __PATRONS_API_VERSION);
strcat(tmp, "↵\n");

// 按行拼接日志
for (int i = 0; i < current_cursor; i++) {
if (dump_logs[i] != NULL) {
strcat(tmp, dump_logs[i]);
strcat(tmp, "↵\n");
}
}
}

strcat(tmp, "\n");
strcat(tmp, "\n");

jstring logs = (*env)->NewStringUTF(env, tmp);
free(tmp);
logs = (*env)->NewStringUTF(env, tmp);
free(tmp);

// Dump 完成后清理缓冲区
if (cleanAfterDump) {
CleanLogBuffer();
// Dump 完成后清理缓冲区
if (cleanAfterDump) {
CleanLogBuffer();
}
}

pthread_mutex_unlock(&log_lock);

return logs;
}
35 changes: 28 additions & 7 deletions patrons/src/main/cpp/patrons_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
#include <errno.h>
#include <stdarg.h>
#include <elf.h>
#include <pthread.h>

// android api 定义
#define __ANDROID_API_R__ 30
#define __ANDROID_API_S__ 31

// patrons version 定义
#define __PATRONS_API_VERSION "1.0.6.4"
#define __PATRONS_API_VERSION "1.0.6.5"

char *dump_logs[128] = {0};
char dump_cursor = 0;
Expand Down Expand Up @@ -93,10 +94,12 @@ bool debuggable;
int api_level;

// 当前机型
char brand[128];
char device[128];
char heapsize[16];
char fingerprint[512];
char brand[64] = {0};
char system_brand[64] = {0};
char device[128] = {0};
char heapsize[16] = {0};
char fingerprint[512] = {0};
char rom_version[128] = {0};

// 函数原型
typedef void *(*stub_method_in_art_)();
Expand Down Expand Up @@ -141,6 +144,8 @@ size_t offset_region_limit_in_region_space;
size_t offset_num_regions_in_region_space;
size_t offset_space_bitmap_in_region_space;

pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER;

bool init_ = false;
bool has_exception_handle_ = false;

Expand Down Expand Up @@ -169,7 +174,7 @@ bool IsAndroidVersionMatch() {
* offset_heap_in_runtime <<= art::Runtime::RunRootClinits() 第一行找到 class_linker_ 往前推10个指针
* offset_region_space_in_heap <<= art::gc::Heap::TrimSpaces() 中间连续三个 if 的最后一个 if (涉及到 art::gc::space::RegionSpace::GetBytesAllocated())
*
* 1. > Android 8 : offset_region_limit_in_region_space <<= art::Heap::Space::RegionSpace::ClampGrowthLimit()
* 1. > Android 8 : offset_region_limit_in_region_space <<= art::Heap::Space::RegionSpace::ClampGrowthLimit(), 找到和右移12的参数进行比较的部分
* 2. <= Android 8 : offset_region_limit_in_region_space = current_region_ -4 <<= art::gc::space::RegionSpace::Clear() 倒数第二个赋值反推
*
* offset_num_regions_in_region_space = offset_region_limit_in_region_space - 4 * 3
Expand Down Expand Up @@ -228,7 +233,7 @@ void DefineOffset() {

break;
case __ANDROID_API_R__: // 11
offset_heap_in_runtime = 0xEC;
offset_heap_in_runtime = 0x114 - 4 * 10;
offset_region_space_in_heap = 0x208;
offset_region_limit_in_region_space = 0x160;

Expand All @@ -240,6 +245,11 @@ void DefineOffset() {
offset_region_space_in_heap = 0x210;
}

// 特殊支持 oppo oneplus 的 color os 12
if (strcasecmp(rom_version, "V12") && (strcasecmp(brand, "oppo") || strcasecmp(brand, "oneplus"))) {
offset_region_space_in_heap = 0x218;
}

// Android 11 多了一个 map
offset_num_regions_in_region_space = offset_region_limit_in_region_space - 4 * 5 - 12;

Expand Down Expand Up @@ -279,13 +289,24 @@ const char *GetArtPath() {
void InitEnv() {
// 厂商
__system_property_get("ro.product.brand", brand);
// 厂商品牌
__system_property_get("ro.product.system.brand", system_brand);
// 型号
__system_property_get("ro.product.model", device);
// 默认堆大小
__system_property_get("dalvik.vm.heapsize", heapsize);
// ROM 信息
__system_property_get("ro.build.fingerprint", fingerprint);

// 拼接自定义 ROM Version 的配置名
char custom_rom_config_name[128] = {0};
strcat(custom_rom_config_name, "ro.build.version.");
strcat(custom_rom_config_name, system_brand);
strcat(custom_rom_config_name, "rom");

// ROM Version
__system_property_get(custom_rom_config_name, rom_version);

api_level = android_get_device_api_level();
}

Expand Down

0 comments on commit 3a9535a

Please sign in to comment.