暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

「测试」工具美眉之性能指标memory

将咖啡转化为程序的工具人 2021-09-08
1803

内存是我们做性能测试时另一个比较重要的指标,当内存使用率大于70%也许就会触发相应的内存告警,于是程序员们就会被紧急拉去小黑屋排查原因,是程序bug导致的内存飙升,还是说真的不够用,需要去申请扩容了。


今天工具美眉将和大家一起讨论一下内存有哪些重要的指标,如何分析?

我整理了一系列内存相关的性能指标

我们可以通过linux命令free -m查看当前的内存情况:-m代表内存统计以M为单位。

1)total,代表的是总计的物理内存的大小

2)used,代表已经使用了多少内存

3)free,剩余可用的内存大小,因此total = used+free

4)  shared,代表多进程间的共享内存大小

5)buffers,指的是对磁盘的临时存储,用来缓存磁盘的数据的空间,通常不会特别大(20MB左右)。有了这个缓存,内核就可以将写操作集中起来,统一合并,一起写回磁盘。

6)cached,是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。

缓存机制是一种用空间换时间的机制,由于内存的速度远大于磁盘速度,操作系统将一些特别常用的磁盘上的数据存在内存中,在用户要访问的时候直接从内存中找出数据展示给用户,这样虽然占用了一些内存的空间,却很大程度的加速了数据的访问。

7)swap,指硬盘上交换分区的使用大小,交换机制不同于缓存机制,是使用时间换空间的。相比磁盘,内存真的小的可怜,我们日常使用的民用计算机一般就是4G、8G4G、8G的内存,磁盘的却有500G、1T500G、1T之大。交换机制就是把一些不常用的内存的数据暂时存储到磁盘上面上去,腾出来的内存空间留作他用,在需要的时候再从磁盘中将数据读入内存中。这样做虽然从真正需要数据到数据展示在户面前的过程变慢了,但却让整个系统拥有了看似更多的内存。

而swap不为0时,代表内存可能不够了,才会占Swap,把磁盘的部分空间当做虚拟内存来使用,所以Swap可以作为服务器监控的一项指标,需要引起我们注意


除了free命令以外,我们还可以通过以下命令,查看更多的内存相关的指标

    cat /proc/meminfo && free

    我们首先来看一下MemAvailable这个指标,它代表的是应用程序可用的内存大小。为什么图中的memFree要明显小于memAvailable?因为系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以MemFree不能代表全部可用的内存,这部分可回收的内存加上MemFree才是系统可用的内存,即:MemAvailable≈MemFree+Buffers+Cached,它是内核使用特定的算法计算出来的,是一个估计值。它与MemFree的关键区别点在于,MemFree是说的系统层面,MemAvailable是说的应用程序层面。


    哪几个指标可以直观看到内存回收的情况?

    LRU list是Linux kernel的内存页面回收算法(Page Frame Reclaiming Algorithm)所使用的数据结构。LRU是Least Recently Used的缩写,这个算法的核心思想是:回收的页面应该是最近使用得最少的。把刚访问过的页面放在列首,越接近列尾的就是越长时间未访问过的页面,这样,虽然不能记录访问时间,但利用页面在LRU list中的相对位置也可以轻松找到年龄最长的页面。

    把刚访问过的页面放进active list,长时间未访问过的页面放进inactive list。

    上图中的active 和inactive分别就代表了activelist和inactivelist的大小。如果inactive list很大,表明在可以回收的页面很多;而如果inactive list很小,说明可以回收的页面不多。

    ACTIVE_ANON和ACTIVE_FILE,分别表示anonymous pages和mapped pages。用户进程的内存页分为两种:与文件关联的内存(比如程序文件、数据文件所对应的内存页)和与文件无关的内存(比如进程的堆栈,用malloc申请的内存。active大小=active_anon + active_file。


    dirty指标代表的是等待被写入磁盘的内存大小。脏页是linux内核中的概念,因为硬盘的读写速度远赶不上内存的速度,系统就把读写比较频繁的数据事先放到内存中,以提高读写速度,这就叫高速缓存,linux是以页作为高速缓存的单位,当进程修改了高速缓存里的数据时,该页就被内核标记为脏页,内核将会在合适的时间把脏页的数据写到磁盘中去,以保持高速缓存中的数据和磁盘中的数据是一致的。

    可以通过如下命令进一步查看dirty的配置:

      sysctl -a | grep dirty

      vm.dirty_background_ratio:10,这些“脏数据”在稍后是会写入磁盘的,pdflush/flush/kdmflush这些后台进程会稍后清理脏数据。举一个例子,我有32G内存,那么有3.2G的内存可以待在内存里,超过3.2G的话就会有进程来清理它。

      vm.dirty_ratio:20,是绝对的脏数据限制,内存里的脏数据百分比不能超过这个值。如果脏数据超过这个数量,新的IO请求将会被阻挡,直到脏数据被写进磁盘。这是造成IO卡顿的重要原因,但这也是保证内存中不会存在过量脏数据的保护机制。生产上设置要小心,尤其是剩余内存不足的时候,会触发dirty_ratio强制进行缓存写磁盘,可能会阻塞应用造成机器hang死的情况。

      vm.dirty_expire_centisecs:43200,指定脏数据能存活的时间。当 pdflush/flush/kdmflush 进行起来时,它会检查是否有数据超过这个时限,如果有则会把它异步地写到磁盘中。毕竟数据在内存里待太久也会有丢失风险。


      当分析内存使用状况时, 内核本身使用的内存也需要考虑, 这种内存叫做slab memory,slab是Linux操作系统的一种内存分配机制,避免内存碎片。可以通过以下命令来查看:

         cat proc/meminfo

        当发现内存swap过大时,可以通过加内存或解决占用内存较大的进程的方式来解决:

          ps aux --sort=rss | head -n

          表示按 rss 排序,取 Top n。

          找到占用内存较大的进程,然后使用jmap命令对进程做进一步分析。jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。可以使用jmap生成Heap Dump。 


          下一次我们一起使用jmap来分析一下java进程的内存情况吧。今天的分享就到这里,如果这篇文章对你有所帮助,请点赞和转发哦👍

          文章转载自将咖啡转化为程序的工具人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论