androidnative内存
A. Android内存性能
最近看到测试同事在模拟Android低内存场景,原来是测试后台Service是否能被杀死。
为了顺利测试,我着手编写了一个内存测试工具,名为Ramtool。
1. 最大可用物理内存
1.1 背景
如何完全占用Android的物理内存,并非简单通过new申请内存就能实现。
Android的Framework在java层,因此App进程需要启动jvm虚拟机,运行在jvm中的程序都会受到jvm最大heap限制。
Android的jvm同样受到system/build.prop控制,现代Android系统默认jvm启动heap为64MB,最大扩容256MB。
1.2 方案
1.2.1 占用内存
总体思路是摆脱android jvm,使用C/C++制作Native动态链接库,直接向Linux内核申请内存。
此外,Native还可以摆脱jvm的操作时内存的cpu损耗,摆脱jvm的gc控制,实现手动释放内存防止影响后续测试。
现代操作系统,包括Linux,都使用了虚拟内存的概念来进行进程间内存隔离。
如果只是不停通过malloc申请堆内存,即使申请的内存容量已经远远超过硬件物理内存,也不会发生OOM崩溃。
1.2.2 工程实现
Native OOM崩溃可能会影响进程稳定性,申请到的内存释放也会很麻烦,所以,放到子进程里去申请heap内存,每次申请1MB,直到子进程崩溃,catch住binder的跨进程通信异常时,就判断为可用的最大物理内存。
在大部分机型上都是没问题的,但在部分超大内存机型上,例如realme的16GB内存机型,单进程系统限制最大内存为10GB,所以为了测试极限物理内存占用,还要采用多进程方案。
申请完内存,记得要在每次测试完成后,即使进行内存释放。内存泄漏会影响后续内存测试的准确性。
1.2.3 结果
6GB ram的红米K30手机上,app最大可用的物理内存极限在4GB左右。
16GB ram的Realme手机上,app最大可用的物理内存极限在11.5GB左右。
2. 内存带宽
2.1 背景
做完最大可用内存后,感觉做都做了,不如再做一个内存带宽测试工具。
市面上的内存带宽测试都太抽象了,不知道对应到代码上具体是什么样的性能。
内存不像是硬盘,可以很直接看到读写性能。
所以应该怎样做呢?
2.2 方案
2.2.1 开源方案
先看下开源的方案都是怎么做的。
2.2.2 硬件原理
我们再来看下CPU的硬件工作方式。
为了最大程度利用内存带宽,所以stream中选择数据类型也使用了double。
所以直接用stream就完了吗?
Stream的方案并不能最大程度发挥内存带宽。
2.2.3 小故事
(此段故事可以跳过阅读)
(故事结束,正文开始)
但实际上内存就是慢的一批,测试发现系统memcpy很慢,开始翻对应Android版本的Linux内核源代码,发现历史上Linux的内存拷贝可以简单理解为就是个for循环,按照最小内存单位进行拷贝...
且现代处理器都支持SIMD指令,例如x86指令集阵营的SSE系列指令集,AVX指令集;arm阵营的neon指令,advanc-simd指令,还有最新arm-v9上的SVE指令,都是SIMD指令集。
使用SIMD指令对于测试内存带宽,可以最大限度避免CPU的影响,提高带宽。
2.2.4 最终方案
参考ARM公司最新的优化库,分段对内存进行拷贝。
使用SIMD指令的memcpy进行内存带宽测试,相比于stream的内存方案,内存带宽大很多。
其他内存操作算法参考stream。
内存带宽测试功能截图:
3. 缓存/内存延迟
3.1 背景
做完内存带宽后,感觉做都做了(梅开二度),专业测试工具怎么能少了内存延迟测试。
CPU只能操作寄存器上的数据,CPU在操作数据前必须要将数据从内存载入到寄存器。
内存太慢了,所以CPU厂商通过SRAM实现了缓存。
缓存对于程序来说是透明的,只能通过细微的逐步扩大容量访问内存才能测得缓存延迟。
所以应该怎样做呢?
3.2 方案
3.2.1 算法
先看看开源是怎么做的。
3.2.2 参数
经过多次实验,步长取2048字节,容量为256MB时,测试结果较为准确,且测试时长可接受。
3.2.3 数据处理
经过上面的步骤,已经可以成功取到内存延迟的数据。
将数据导入excel,先画图观察下数据曲线。
首先访问命中cache,随着访问容量增大,逐渐冲破cache容量,cache命中率下降。
算法实现:
3.2.4 结果
通过数据分析,计算出cache和内存的延迟平台的均值大小,还用数据画了个折线图:
4. 总结
似乎目前市面上Android平台还没有比较专业倾向的内存测试工具,简陋封装了下UI,发布到了github,让大家有的用。
测试结果仅具备横向机型间对比。
Ramtool项目地址:github.com/park671/Ramt...
拒绝白嫖,从你我做起,给个star再拿代码~