测试场景之内存或磁盘空间不足

标签: 测试小工具

内存、磁盘空间不足 是测试场景中比较常见的一种异常场景

目录

内存、磁盘空间的定义及监控

标题中所指的内存和磁盘在【pc-windows】分别指什么?【内存】、【硬盘(磁盘)】

标题中所指的内存和磁盘在【android】分别指什么?

标题中所指的内存和磁盘在【IOS】中分别指什么?

磁盘空间不足的场景模拟

PC-windows端

安卓端

IOS端

内存不足的场景模拟

pc-windows端

安卓端

IOS端


内存、磁盘空间的定义及监控

 

标题中所指的内存和磁盘在【pc-windows】分别指什么?【内存】、【硬盘(磁盘)

 

让我们先来看看,资源监视器窗口中的内存、磁盘选项卡:

  • 内存选项卡:显示整体的物理内存消耗量和各个进程的消耗量;已用物理内存的图表,提交更改,以及硬中断/秒

 

计算机运行时,计算机的主内存按照被使用情况可分类为:(8GB=88192MB=2554+63+5002+573)

  • 可利用(Available)物理内存:可立即分配给程序使用的内存。-(2554MB=651+1903) 包括:
    • 空闲(Free)物理内存:完全未被使用,内容为全0 -(651MB)
    • 备用(standby)物理内存:操作系统预先把可能要用到的硬盘数据加载所占用的内存,还没被用户进程所使用,因此可随时丢弃从新初始化为0. 这部分可被算入可利用物理内存,也可以算入缓存物理内存-(1903MB)
  •  缓存(Cached)物理内存(1966MB=63+1903):
    • 已修改(modified)物理内存:已被修改过的caching用途的内存,可在任意时刻写回硬盘文件(不是分页文件)然后被重用。由于硬盘I/O,已修改(modified)物理内存不能计入空闲(Free)物理内存-(63MB)
  • 被使用(used)物理内存:已经被进程使用的内存- (5002MB) 
    • 用户进程使用的物理内存(用户空间),即工作集(Working set)=‘专用工作集' + '共享工作集'。 '共享工作集’:可能被其他程序共享的内存, 例如DLL。

Private Bytes是只被本进程提交(commit)的虚拟地址空间,不包括其他进程共享的内存。Virtual Byte是整个进程占用的全部虚拟地址空间。32位Windows用户模式下,进程最大可以使用2GiB,可以通过修改Boot.ini文件扩展为最大可以使用到3GiB。

    • 核心进程使用的物理内存(内核空间)
      • 分页的核心进程使用的物理内存:可以交换到分页文件中,从而可被回收的物理内存
      • 未分页(Non paged)的核心进程使用的物理内存:不能交换到分页文件的内存,总是要保留在物理内存中
  • 硬件保留(hardware reserved)的物理内存:被CPU中的GPU核心或者其他外设硬件占用的,不由操作系统使用的内存。-(573MB)

 

  • 物理内存:即随机存取存储器(random access memory,RAM)又称作“随机存储器”,也叫主存、内存(中文真的很容易弄混这些意思),如上示例该机器的物理内存大小为8G
  • 虚拟内存:虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。它就是进程运行时所需的所有内存空间的总和。
  • 磁盘选项卡:显示磁盘活动的进程,磁盘活动,以及存储;磁盘使用的图表(KB/秒)和磁盘队列长度
  • 磁盘:磁盘这个词容易产生歧义,但一般所指的是硬盘。电脑的C、E盘是磁盘上划分的逻辑分区,磁盘大小为总字节数,磁盘剩余空间为总可用字节数。

 

标题中所指的内存和磁盘在【android】分别指什么?

【内存】

  1、概念说明:

  • RAM,Random-Access Memory 随机存取存储器,即运行时内存 (如下图 示例手机运行内存为4G)。一般在1G-8G之间,容量越大,处理数据运算越快,对于手机来说最直观的感受就是可以同时运行很多软件,迅速的在不用软件之间进行切换,响应速度更快。

  

  手机的总运行时内存可以在设置中查看,但测试app时,我们更关心的是app运行时占用的内存情况。

Android应用都是在Android的虚拟机上运行, 应用程序的内存分配与垃圾回收都是由虚拟机完成的。 

Android内存运行时堆如下图:(Dalvik:Android 4.4及其以下平台使用的虚拟机;ART:Android 4.4以上平台使用的虚拟机)

 

 

 

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

 

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、使用第三方工具填充内存:

例如:哆啦A梦-移动测试工具的百宝箱,搜狗测试出品

目的2:为了检测应用在用户不同使用强度下消耗手机内存和CPU的情况,如果内存消耗过大会造成手机使用时卡顿,闪退等现象,进而影响用户体验,甚至会影响日活数据和用户留存等情况。进行安卓应用内存测试

方法如下:压力测试工具(monkey等)+内存监控工具

IOS端

待补充

原文链接:加载失败,请重新获取