内存、磁盘空间不足 是测试场景中比较常见的一种异常场景
目录
标题中所指的内存和磁盘在【pc-windows】分别指什么?【内存】、【硬盘(磁盘)】
内存、磁盘空间的定义及监控
标题中所指的内存和磁盘在【pc-windows】分别指什么?【内存】、【硬盘(磁盘)】
让我们先来看看,资源监视器窗口中的内存、磁盘选项卡:
- 内存选项卡:显示整体的物理内存消耗量和各个进程的消耗量;已用物理内存的图表,提交更改,以及硬中断/秒
计算机运行时,计算机的主内存按照被使用情况可分类为:(8GB=88192MB=2554+63+5002+573)
Private Bytes是只被本进程提交(commit)的虚拟地址空间,不包括其他进程共享的内存。Virtual Byte是整个进程占用的全部虚拟地址空间。32位Windows用户模式下,进程最大可以使用2GiB,可以通过修改Boot.ini文件扩展为最大可以使用到3GiB。
|
---|
- 物理内存:即随机存取存储器(random access memory,RAM)又称作“随机存储器”,也叫主存、内存(中文真的很容易弄混这些意思),如上示例该机器的物理内存大小为8G
- 虚拟内存:虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。它就是进程运行时所需的所有内存空间的总和。
- 磁盘选项卡:显示磁盘活动的进程,磁盘活动,以及存储;磁盘使用的图表(KB/秒)和磁盘队列长度
- 磁盘:磁盘这个词容易产生歧义,但一般所指的是硬盘。电脑的C、E盘是磁盘上划分的逻辑分区,磁盘大小为总字节数,磁盘剩余空间为总可用字节数。
标题中所指的内存和磁盘在【android】分别指什么?
【内存】
1、概念说明:
- RAM,Random-Access Memory 随机存取存储器,即运行时内存 (如下图 示例手机运行内存为4G)。一般在1G-8G之间,容量越大,处理数据运算越快,对于手机来说最直观的感受就是可以同时运行很多软件,迅速的在不用软件之间进行切换,响应速度更快。
手机的总运行时内存可以在设置中查看,但测试app时,我们更关心的是app运行时占用的内存情况。
-
Android内存管理机制:参考 【Android应用性能优化最佳实践 (移动开发) .2017. 机械工业出版社】
Android应用都是在Android的虚拟机上运行, 应用程序的内存分配与垃圾回收都是由虚拟机完成的。
Android内存运行时堆如下图:(Dalvik:Android 4.4及其以下平台使用的虚拟机;ART:Android 4.4以上平台使用的虚拟机)
- app运行时的内存占用情况:Android内存(1): app内存浅析
- 内存分析工具
Memory Monitor
Heap Viewer(查看堆的使用情况)、Allocation Tracker(跟踪内存分配情况)——代码执行时出现了频繁的GC,Heap Alloc内存大幅度波动。这种情况通常是分配了许多临时变量或数组,随后又被迅速回收,这种情况在确定具体场景后适合使用这些工具查看具体分配的对象
DDMS
MAT——Android虚拟机能记录下问题发生时系统的部分运行状态和内存使用情况Java Heap,并将其存储在堆转储(HeapDump)文件中。分析该文件最简单的工具即MAT,MAT可以帮助开发者定位导致内存泄漏的对象,以及发现大的内存对象,然后解决内存泄漏并通过优化内存对象,达到减少内存消耗的目的。
LeakCanary——随着功能的反复执行,Heap内存一直在持续增长,这种情况最适合用LeakCanary等泄漏检查工具进行白盒测试分析
adb:dumpsysmeminfo <package_name>或dumpsys meminfo <package_id>
adb打印信息关注如下几个字段:
(1) Native/Dalvik 的 Heap alloc(堆中已被分配的内存)
分别是JNI层和Java层的内存分配情况,如果发现这个值一直增长,则代表程序可能出现了内存泄漏。
(2) Total 的 PSS 信息(实际使用的物理内存总量)
这个值就是应用真正占据的内存大小,通过这个信息,你可判别手机中哪些程序占内存比较大。
如果Heap Alloc变化不大,但进程的Dalvik Heap Pss(Proportional Set Size)内存明显增加。这种情况比较少见,是由于分配了大量小对象造成的内存碎片。
- app运行时能占用的内存限制:
Android系统为每一个应用程序都设置一个硬性的DalvikHeapSize最大限制阈值,这个阈值在不同的设备上会因为RAM大小不同而有所差异。如果应用占用内存空间已经接近这个阈值时,再尝试分配内存的话,就很容易引发OutOfMemoryError错误。ActivityManager.getMemoryClass()可以用来查询当前应用的HeapSize阈值,这个方法会返回一个整数,表明应用的HeapSize阈值是多少MB。
【磁盘(硬盘)】
1、概念说明:手机内存在逻辑上包括ROM、内部内存和外部内存。(可以理解为电脑的硬盘) (如下图 示例手机的手机内存为64G)
- Rom(Read Only Memory只读存储器):逻辑上这部分文件只能读取。可以理解为系统文件,如果损坏就会导致手机系统无法启动或者运行
- 内部存储-InternalStorage:存储私有数据,用来存储系统文件和应用的私有文件,一般用来存储首选项,数据库等文件。
- 外部存储-ExternalStorage:存储公共数据,一般用来存储照片、音乐等等可以看到的文件 。
手机内存容量一般在16G-512G之间,有些手机可以通过SD卡或者TF卡对容量进行扩充,内存越大,可以储存的文件越多。现在,手机机身本身的存储容量(内置存储)越来越大,一般不需要外置sd卡(拓展性的储存卡)。
2、了解手机内存中的内部存储和外部存储及其对应的数据持久化方法
彻底搞懂Android文件存储---内部存储,外部存储以及各种存储路径解惑;彻底理解android中的内部存储与外部存储
https://developer.android.com/guide/topics/data/data-storage
- 文件存储-https://developer.android.com/training/data-storage/files
- SharedPreferences-https://developer.android.com/training/data-storage/shared-preferences
- SQLite数据库存储-https://developer.android.com/training/data-storage/room
3、查看手机内存大小的方式:文件管理器中可以查看手机内存的使用情况(可用空间、已用空间)
标题中所指的内存和磁盘在【IOS】中分别指什么?
(由于对ios的接触不多,这里不做过多展开,相关内容见 - WWDC 2018:iOS 内存深入研究 - 掘金)
磁盘空间不足的场景模拟
目的:经常需要测试软件在该情况下是否正常安装、运行或者提示相关异常。这些测试的主要目的是确保软件在资源不足的情况下不会崩溃。
模拟的方式一般是通过增加文件数、大小的方式去填充空间
PC-windows端
(1)python
import os, sys,ctypes
# def disk_stat(path):
# """
# 仅适用于Linux 或python2.7
# 查看文件夹占用磁盘信息
# :param folder: 文件夹路径
# :return:
# """
# hd={}
# disk = os.statvfs(path)
# print(disk)
# # 剩余
# hd['free'] = disk.f_bavail * disk.f_frsize
# # 总共
# hd['total'] = disk.f_blocks * disk.f_frsize
# # 已使用
# hd['used'] = hd['total'] - hd['free']
# # 使用比例
# hd['used_proportion'] = float(hd['used']) / float(hd['total'])
# return hd
if __name__ == '__main__':
print(sys.version)
path = input("请输入文件夹路径:")
"""
https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getdiskfreespaceexw
windows api 中的GetDiskFreeSpaceExW()
它有一个参数,路径,它有3个输出参数,即空闲字节(可用于调用者),总字节数(磁盘大小)和总可用字节数.
只需在调用它时,为想要获取的所有信息提供变量(指针)
"""
total_bytes = ctypes.c_ulonglong(0)
free_bytes = ctypes.c_ulonglong(0)
ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(path), None, ctypes.pointer(total_bytes), ctypes.pointer(free_bytes))
print("该路径下总字节数(磁盘大小)为:" + str(total_bytes.value / 1024 / 1024 / 1024 )+ "G")
print("该路径下总可用字节数(磁盘剩余空间)为:" +str( free_bytes.value / 1024 / 1024 / 1024 )+ "G")
"""
https://www.runoob.com/python3/python3-os-file-methods.html
"""
#os.access(path, mode);
print(os.stat(path).st_size)
print(os.access(path,os.F_OK))#是否存在
print(os.access(path, os.R_OK))#是否可读
print(os.access(path, os.W_OK))#是否可写
print(os.access(path, os.X_OK))#是否可执行
unit = input("请输入想填充文件大小的单位(M / G):\n")
if unit in ("M","m"):
units=1024 * 1024
elif unit in ("G","g"):
units = 1024 * 1024 * 1024
else:
units=0
print(units)#1G=1073741824 B字节
size = int(input("请输入想填充文件大小的数值:\n"))
sizes = int(units * size)
# 打开文件
"""
os.open(file, flags[, mode]);
flags -- 该参数可以是以下选项,多个使用 "|" 隔开:
os.O_RDWR : 以读写的方式打开
os.O_CREAT: 创建并打开一个新文件
"""
fd = os.open("diskadd.txt", os.O_RDWR | os.O_CREAT)
# os.write(fd,("a"*sizes)).encode()#一次性写入太大的字符 会报MemoryError
# 写入字符串-以分批字节的形式写入 由于打开方式是rw
#ret = os.write(fd,bytes(str, 'UTF-8'))
for i in range(int(sizes/2048)):
os.write(fd,("a"*2048).encode())
# 强制将文件写入磁盘
os.fsync(fd)
print(os.fstat(fd).st_size)
# 关闭文件
os.close(fd)
print("文件已关闭")
print("是否删除已增加的文件: 1=是 2=否")
a = int(input())
if a == 1:
os.remove("diskadd.txt")
print("填充内存的文件已删除")
else: print("end")
(2)C# https://github.com/dandzm/DiskFiller
https://www.cnblogs.com/dandzm/p/4956810.html
使用效果如下:
安卓端
方法如下:
1、开发一个测试工具app,使用数据持久化方法填充安卓手机的存储空间
已有的第三方工具如:哆啦A梦-移动测试工具的百宝箱,搜狗测试出品
使用截图如下:
IOS端
待补充
内存不足的场景模拟
一般测试情况下,不会特意去令设备环境处于内存不足的情景,反而是会检查程序、软件本身在正常操作强度下、稍高频操作下是否内存使用正常、内存释放合理、不出现内存泄漏或OOM等异常,即针对应用软件本身的内存测试。
pc-windows端
待补充
安卓端
目的1:如果在测试过程中,发现手机在很卡顿的时候,被测程序出现异常,那么这种情况下就需要在另一台设备上证明这个问题也会复现,即模拟出内存不足的情况
方法如下:
1、在手机的开发者选项中,开启应用不保留活动的按钮,模拟内存不足时活动被回收的情况
2、使用第三方工具填充内存:
目的2:为了检测应用在用户不同使用强度下消耗手机内存和CPU的情况,如果内存消耗过大会造成手机使用时卡顿,闪退等现象,进而影响用户体验,甚至会影响日活数据和用户留存等情况。进行安卓应用内存测试
方法如下:压力测试工具(monkey等)+内存监控工具
IOS端
待补充