测试基础 内存基础知识

CKL的思考 · 2022年08月31日 · 最后由 magicyang 回复于 2022年09月02日 · 8053 次阅读

在计算机的组件中,内存是非常重要的存在。在做性能测试的过程中,针对内存的监控也是非常核心的一类指标项。在一些场景的沟通中,发现大家对于内存的理解可能存在一些偏差。本文结合笔者的经验,对内存做一些基础知识的汇总。

01

为什么会有内存的存在?

在冯.诺依曼结构的核心设计思想中,计算机的五个基本组成部分:运算器、控制器、存储器、输入设备、输出设备。其中的存储器指主要功能是存储程序和各种数据,并且能够在计算机运行过程高速、自动地完成程序或者数据的存储。存储器可以分为内部存储器(内存)和外部存储器(硬盘)。

早期的内存是固化在主板上,可存储的数据有限。随着 CPU 的工艺技术不断发展,速度越来越快(I7 的 CPU,主频可达到 2.69GHz)),但是硬盘由于机械结构的局限性(读写速度 120MB/S),无法跟上 CPU 的节奏,从而造成 CPU 资源的闲置。于是就有的独立的内存(读写速度大约在 7~9GB/s),用于把常用数据从硬盘中读取出来(Cached ),供 CPU 快速使用,同时,把经 CPU 处理过的数据暂存在内存中(Buffers),后续再固化到硬盘中。

这个过程是不是很像我们现在的 业务 —> redis —> 数据库的结构。

02

如上图所示,不同操作系统对于内存的管理机制也是不一样的。简单来说,Windows 对于内存的管理就是省着用,而对于 Lixnu 来说,就是能用多少就用多少,尽可能用。

03

在性能测试过程中,我们对于 Linux 操作系统的内存查看,一般会通过 Free 命令来看,如下图所示,在算可用内存的时候,是 free+buff/cache,而不单单只看 free 的值。因为 buff/cache 在需要的时候,可以快速被释放,变成内存使用。也可以通过命令来手动释放这类内存。

echo 3 >proc/sys/vm/drop_caches

那么,在 Linxu 中,内存什么时候真的不够用了呢?就是 Swap 有值了,Swap 指的是硬盘上交换分区的使用大小。设计的目的就是当上面提到的 +buffers/cache 表示的可用内存都已使用完,新的读写请求过来后,会把内存中的部分数据写入磁盘,从而把磁盘的部分空间当作虚拟内存来使用。

04

那我们通常所说的内存泄漏又指的是什么呢?

内存泄漏一般指的是某个对象的引用丢失,无法再访问到该引用,但是该引用却依旧引用着某个对象,导致这个对象无法回收,最终导致内存溢出 OOM。简单而言,就是内存里的对象无法被引用,也无法被回收,一直占用着不释放,导致内存的可使用量减少。在面试过程中,如果没有特别说明,内存泄漏指的是 JVM 内存的泄露(JAVA 是当下企业的主流研发语言,所以一般情况下探讨的是这类问题,其他语言当然也存在,但是相对来说没那么严重,原因是其他语言都是直接使用物理内存,量比较大,而 JAVA 使用的是 JVM 内存,一般都只会设置在 2G 左右,过高会严重影响 GC 效率,导致服务不可用)。

那么,如何判断 JVM 是否存在泄露呢?目前主流的工具(Visualvm、jstack、Jprofiler 等)都会提供相对应的功能,在发生 GC 的时候,如果发现每次 GC 的量在不断地变小,且 GC 的频率越来越快,那么就有可能是内存泄露了。这个时候就需要去看看 JVM 里存放了哪些大对象。上面提到的工具都可以查看,具体的工具使用,可自行百度。

05

对于测试的同学,不管是专注于哪类测试,对于计算机的工作原理都需要有一定的了解,基础需要打牢固

留几个小问题,供大家思考:

  1. 程序从编译到被 CPU 处理,会经过哪些步骤?

  2. 通过网络接口传输的数据,是直接被 CPU 处理,还是先到内存或者硬盘?

  3. 性能圈流行一句话叫一切问题皆 IO,是不是有道理的?原理是什么呢?

原文链接: https://mp.weixin.qq.com/s/giYUGWDhD3kZQxVKwPGIZg

共收到 12 条回复 时间 点赞
1楼 已删除
大瓶子 回复

可以确保周更。。。😅

从我的角度来看,这篇文章更值得去反思。
性能测试的路会不会开始就是错的?
工具应该仅仅是手段,而不是目的。当个体只能使用工具,却无法对工具进行针对修改的时候,人会更多的被工具限制。
从楼主的介绍来说,可能随便一个本科的课程都比楼主说的详细。
楼主提的问题,其实我想问楼主,你的答案呢?然后你的答案又从何而来?哪些是你自己的东西?

不是为了引战,只是在想,未来技术只会越来越深,这种对技术的粗浅理解,真的太容易被替代了。
PS:当然也可以说我只要比别人跑的快,死道友不死贫道,怕啥。。。

催更催更催更

1.使用高级语言编写的程序,会存储在硬盘上。通过编译转为机器指令,放置内存中执行。
CPU 会进行取指令 分析指令 读取操作数 执行命令 存放结果

2.CPU 是直接和内存打交道的。通过网络接口传输的数据属于外部设备,通过外部总线将数据传入到内存中,才能被 CPU 处理

果断关注,我喜欢那句话 不为技术服务的 都是伪技术

magicyang 回复

感谢回复,按着你的思考,尝试回答下几个问题:
1.性能测试的路会不会开始就是错的?

性能测试现在是处理比较尴尬的地位,上不去,下不来。随着现在各类研发框架的完善和流行,只要开发不乱来,浅层的性能问题会越来越少,只会简单的压测意义不大。而深层次的问题,中小企业的研发能力又不一定能修复(比如中间件的问题,框架本身的局限性等)。

同时,随着硬件的工艺改进,当下的服务器足以满足中小企业的日常性能需求,团队对于性能测试的渴求度也没那么高。

所以,走性能这条路,要么走深,要么就不选。这也是我近几年逐渐转方向的原因(本人在大型企业做过性能测试负责人)

2.从楼主的介绍来说,可能随便一个本科的课程都比楼主说的详细。

不敢和本科课程比较,本来就是一时兴起写的,篇幅的原因,没有展开来详细写。只是纯粹的小科普。

3.楼主提的问题,其实我想问楼主,你的答案呢?然后你的答案又从何而来?哪些是你自己的东西?

我的答案在我心中呀,自己真实落地实践过,所以应该算是我的东西吧。之前为了做好性能测试,把《计算机组成原理》一书啃了好多遍。

4.未来技术只会越来越深,这种对技术的粗浅理解,真的太容易被替代了

原则上来说,我们不需要对所有的技术做很深刻的理解,本质工作的能力,当然是越深越好。但是一些常识性的东西,粗浅理解比不了解要好,了解比不知道要好。留点映像,以待用时。

5.我只要比别人跑的快,死道友不死贫道,怕啥。

这个是对的,先发优势总是占优的。

最后,发贴的意义在于写自己想写的,并引发一些讨论,补充自己的不足。至于是粗浅理解还是精通优秀,都是因人而异,每个人都有自己的擅长和知识盲区。欢迎讨论。

CKL的思考 回复

我是做这个方向的。所有才有这样的疑问。
计算机组成原理的基础主要包括核心的几部分:

  1. CPU 的流水线设计,通常我们所说的 5 级流水线。这里面不同的指令,操作的内容不同。
  2. 内存的多级设计,包括 L1,L2,L3 的设计,为什么要设计多级缓存?芯片内部的缓存寻址策略。

回到软件层面上,目前通用的并行手段,CPU 级别主要是多线程,管程,SIMD 向量指令。
在计算层面,主要是 SIMT 的框架,如 CUDA。
不同的代码编写方式,使用不同的软件框架,可能会有数 10 倍的性能差距。
如果做到一定程度,需要有编译器的知识,理解如何去合理利用寄存器,利用图算法去减少指令,利用依赖分析去并行分发指令,等等。

回到内存的话题来,内存是需要严格控制的,对我们来说要严格控制 HOST<->DEVICE 间的内存 COPY 次数,尽量重复使用片上内存。同时程序设计时,需要用好 L2 内存,尽量在多 THREAD 情况下,减少 BLOCK 的内存读写次数。做深还需要考虑如 GPU 内部的线程调度方式,L2 的内存也要针对的做一定修改。

我说这些的意思就是就算我写出来的程序在 IO 上跑不到极限,也不是测试能测得出来的。

然后你说性能越来越弱,这个是事实,至少目前性能是需要给功耗让位的。但我觉得我们说的应该不是一个点,你说的弱,主要还是没人会改。现在开源的复杂度,能改的确实没几个,而且为了通用性一定会牺牲性能。我说的观点是能耗相对性能更重要,同时国内底层软件栈的人稀少,做通用更难,性价比也偏低。

好巧不巧,我好像昨天看到 NVIDIA 有做这部分性能测试的职位,所以才有一问。

好多文章都说 “可用内存 = free+buff/cache”,但就我实际做性能测试这么多年来说,free 没有了,等着程序崩掉吧,buff/cache 并没有那么容易释放出来的。

magicyang 回复

角度不太一样,感觉您这边更多的是从硬件层的调度和性能分析为看的。而我是从应用层的角度来分析,需要知道的一些知识点,关注点不一样。

从应用的性能来说,关注的基本还是基本逻辑是否能跑通,是否能够充分调度到硬件资源。硬件层本身的性能瓶颈,应用层是没办法突破的。

希望硬件性能能有大的性能突破,这样应用层就可以 “任性” 一点。

CKL的思考 回复

😓,我是纯软件的,也不会自己造硬件,硬件都是拿来主义。
这么说吧,就只讨论 CPU,应用层主要是调度。
如何合理的利用线程资源,线程资源是否独立,线程访存的数据独立性。
能否使用 VECTOR 向量,如 SSE,NEON 等进行加速?
这些都是软件范畴。
只能这么说吧,通常意义上的多数应用软件,其实并没有那么高的实时要求,所以对计算性能要求并不高。
也不会需要用性能优化方法去尝试优化包括底层通用库,因为对人,对成本都是考验。

但是你得这么想啊,你如果只能跑过三方工具,给个报告,这事和点点点区别又有多大呢。。。至少也得有我通过工具可以测试什么,关注点是什么,怎么闭环推动研发改进,如何改进吧。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册