首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >频繁分配释放内存导致的性能问题的分析

频繁分配释放内存导致的性能问题的分析

作者头像
早起的鸟儿有虫吃
发布于 2019-05-05 08:36:17
发布于 2019-05-05 08:36:17
7.2K0
举报
文章被收录于专栏:算法之美算法之美

现象

1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看(pidstat也可以),

发现majflt每秒增量为0,而minflt每秒增量大于10000。

初步分析

majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误。 这两个数值表示一个进程自启动以来所发生的缺页中断的次数。

当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1 检查要访问的虚拟地址是否合法 2 查找/分配一个物理页 3 填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 4 建立映射关系(虚拟地址到物理地址) 5 重新执行发生缺页中断的那条指令 如果第3步,需要读取磁盘,那么这次缺页中断就是majflt,否则就是minflt。 此进程minflt如此之高,一秒10000多次,不得不怀疑它跟进程内核态cpu消耗大有很大关系。

分析代码

查看代码,发现是这么写的:一个请求来,用malloc分配2M内存,请求结束后free这块内存。看日志,发现分配内存语句耗时10us,平均一条请求处理耗时1000us 。 原因已找到! 虽然分配内存语句的耗时在一条处理请求中耗时比重不大,但是这条语句严重影响了性能。要解释清楚原因,需要先了解一下内存分配的原理。

测试:

  1. 循环new分配64K * 2048的内存空间,写入脏数据后,循环调用delete释放。top看进程依然使用131M内存,没有释放。 —— 此时用brk
  2. 循环new分配128K * 2048的内存空间,写入脏数据后,循环调用delete释放。top看进程使用,2960字节内存,完全释放。 —— 此时用mmap
  3. 设置M_MMAP_THRESHOLD 256k,循环new分配128k * 2048 的内存空间,写入脏数据后,循环调用delete释放,而后调用malloc_trim(0)。top看进程使用,2348字节,完全释放。 ——此时用brk

内存分配的原理

从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。brk是将数据段(.data)的最高地址指针_edata往高地址推,mmap是在进程的虚拟地址空间中(一般是堆和栈中间)找一块空闲的。这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。 在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk,mmap,munmap这些系统调用实现的。 下面以一个例子来说明内存分配的原理:

1.进程启动的时候,其(虚拟)内存空间的初始布局如图1所示。其中,mmap内存映射文件是在堆和栈的中间(例如libc-2.2.93.so,其它数据文件等),为了简单起见,省略了内存映射文件。_edata指针(glibc里面定义)指向数据段的最高地址。

2.进程调用A=malloc(30K)以后,内存空间如图2:malloc函数会调用brk系统调用,将_edata指针往高地址推30K,就完成虚拟内存分配。你可能会问:只要把_edata+30K就完成内存分配了?事实是这样的,_edata+30K只是完成虚拟地址的分配,A这块内存现在还是没有物理页与之对应的,等到进程第一次读写A这块内存的时候,发生缺页中断,这个时候,内核才分配A这块内存对应的物理页。

也就是说,如果用malloc分配了A这块内容,然后从来不访问它,那么,A对应的物理页是不会被分配的。

3.进程调用B=malloc(40K)以后,内存空间如图3.

4 进程调用C=malloc(200K)以后,内存空间如v:默认情况下,malloc函数分配内存,如果请求内存大于128K(可由M_MMAP_THRESHOLD选项调节),那就不是去推_edata指针了,而是利用mmap系统调用,从堆和栈的中间分配一块虚拟内存。这样子做主要是因为brk分配的内存需要等到高地址内存释放以后才能释放(例如,在B释放之前,A是不可能释放的),而mmap分配的内存可以单独释放。当然,还有其它的好处,也有坏处,再具体下去,有兴趣的同学可以去看glibc里面malloc的代码了。

5进程调用D=malloc(100K)以后,内存空间如图5.

6 进程调用free(C)以后,C对应的虚拟内存和物理内存一起释放 图6

7 进程调用free(B)以后,

如图7所示。B对应的虚拟内存和物理内存都没有释放,因为只有一个_edata指针,如果往回推,那么D这块内存怎么办呢?当然,B这块内存,是可以重用的,如果这个时候再来一个40K的请求,那么malloc很可能就把B这块内存返回回去了。

8进程调用free(D)以后,如图8所示。B和D连接起来,变成一块140K的空闲内存。 9默认情况下:当最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,执行内存紧缩操作(trim)。在上一个步骤free的时候,发现最高地址空闲内存超过128K,于是内存紧缩,变成图9所示。 真相大白

说完内存分配的原理,那么被测模块在内核态cpu消耗高的原因就很清楚了:每次请求来都malloc一块2M(大于128k)的内存,默认情况下,malloc调用mmap分配内存,请求结束的时候,调用munmap释放内存。假设每个请求需要6个物理页,那么每个请求就会产生6个缺页中断,

在2000的压力下,每秒就产生了10000多次缺页中断,这些缺页中断不需要读取磁盘解决,所以叫做minflt;缺页中断在内核态执行,因此进程的内核态cpu消耗很大。缺页中断分散在整个请求的处理过程中,所以表现为分配语句耗时(10us)相对于整条请求的处理时间(1000us)比重很小。 解决办法

将动态内存改为静态分配,或者启动的时候,用malloc为每个线程分配,然后保存在threaddata里面。但是,由于这个模块的特殊性,静态分配,或者启动时候分配都不可行。另外,Linux下默认栈的大小限制是10M,如果在栈上分配几M的内存,有风险。

禁止malloc调用mmap分配内存,禁止内存紧缩。 在进程启动时候,加入以下两行代码: mallopt(M_MMAP_MAX, 0); // 禁止malloc调用mmap分配内存 mallopt(M_TRIM_THRESHOLD, -1); // 禁止内存紧缩

效果:加入这两行代码以后,用ps命令观察,压力稳定以后,majlt和minflt都为0。进程的系统态cpu从20降到10。 小结

可以用命令ps -o majflt minflt -C program来查看进程的majflt, minflt的值,这两个值都是累加值,从进程启动开始累加。在对高性能要求的程序做压力测试的时候,我们可以多关注一下这两个值。

如果一个进程使用了mmap将很大的数据文件映射到进程的虚拟地址空间,我们需要重点关注majflt的值,因为相比minflt,majflt对于性能的损害是致命的,随机读一次磁盘的耗时数量级在几个毫秒,而minflt只有在大量的时候才会对性能产生影响。

glibc 大内存是128k

tcmalloc是Google开源的一个内存管理库,

小对象(<=32K),大对象4k

jemalloc是facebook推出的

Small: [8], [16, 32, 48, …, 128], [192, 256, 320, …, 512], [768, 1024, 1280, …, 3840] Large: [4 KiB, 8 KiB, 12 KiB, …, 4072 KiB] Huge: [4 MiB, 8 MiB, 12 MiB, …]

来源:

https://cloud.tencent.com/developer/article/1138651

https://www.cnblogs.com/kongzhongqijing/articles/5147411.html

http://www.cnhalo.net/2016/06/13/memory-optimize/

https://blog.csdn.net/junlon2006/article/details/77854898

https://www.jianshu.com/p/f1988cc08dfd

http://tinylab.org/memory-allocation-mystery-%C2%B7-jemalloc-b/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Offer多多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【深度学习自动上色,数月工作几秒完成】开源神经网络图片上色技术解析
【新智元导读】本文是作者对Reddit社区用户Amir Avni深度学习上色机器人的实现,看完本文后,你也能打造媲美大师级着色效果的自动上色神经网络应用。此外,还有一个好处,即使失败了(例如本文头图,见上),你也可以说这是艺术:) 如今,上色都是人手工用Photoshop做的,一张图片要花好几个月才能完成,需要进行大量调查研究,光是其中的一张脸就需要多达20层图层。但是,基于深度神经网络的自动着色机器人,可以几秒钟就实现PS几个月的效果,而且成效越来越惊人。 下面,我们将分三个步骤展示如何打造你自己的着色神
新智元
2018/03/22
2K0
【深度学习自动上色,数月工作几秒完成】开源神经网络图片上色技术解析
用AI给黑白照片上色,复现记忆中的旧时光
【导读】我们知道,深度学习几乎已经应用在每一个领域,但如果我们能够构建一个基于深度学习的模型,让它能够给老照片着色,重现我们童年的旧回忆,这该多么令人激动啊!那么我们要怎么做呢?本文的作者将为大家介绍一个教程,通过深度学习方法为黑白老照片自动上色,带我们重新忆起那段老时光!
AI科技大本营
2018/09/28
1.9K0
用AI给黑白照片上色,复现记忆中的旧时光
keras学习笔记-黑白照片自动着色的神经网络-Alpha版
如今,上色都是人手工用Photoshop做的,一张图片要花好几个月才能完成,需要进行大量调查研究,光是其中的一张脸就需要多达20层图层。但是,基于深度神经网络的自动着色机器人,可以几秒钟就实现PS几个月的效果,而且成效越来越惊人。 下面,我们将分三个步骤展示如何打造你自己的着色神经网络。第一部分讲解核心逻辑。我们将构建一个40行代码的神经网络,作为“Alpha”着色机器人,这个代码片段实际上没有太多的魔法,但可以让你熟悉基本操作。 然后,我们将创建一个可以泛化的神经网络——“Beta”版本。Beta机器人能
用户1332428
2018/03/09
1.4K0
keras学习笔记-黑白照片自动着色的神经网络-Alpha版
教程 | 百行代码构建神经网络黑白图片自动上色系统
选自freecodecamp 作者:Emil Wallnér 机器之心编译 使用神经网络对图片进行风格化渲染是计算机视觉领域的热门应用之一。本文将向你介绍一种简单而有效的黑白图片上色方法,仅需 100 行代码,你也可以搭建自己的神经网络,几秒钟内让计算机自动完成手动工作需要几个月的任务。 今年 7 月,Amir Avni 用神经网络向 Reddit 的 Colorization 社区宣战——那是一个为历史黑白照片上色的版面,用户们通常使用的工具是 Photoshop。 社区用户们惊讶于 Amir 的深度
机器之心
2018/05/10
1.8K0
keras学习笔记-黑白照片自动着色的神经网络-Beta版
Alpha版本不能很好地给未经训练的图像着色。接下来,我们将在Beta版本中做到这一点——将上面的将神经网络泛化。 以下是使用Beta版本对测试图像着色的结果。 特征提取器 我们的神经网络要做的是发现
用户1332428
2018/03/09
7080
keras学习笔记-黑白照片自动着色的神经网络-Beta版
前端慌不慌?用深度学习自动生成HTML代码
选自Floydhub 作者:Emil Wallner 机器之心编译 如何用前端页面原型生成对应的代码一直是我们关注的问题,本文作者根据 pix2code 等论文构建了一个强大的前端代码生成模型,并详细解释了如何利用 LSTM 与 CNN 将设计原型编写为 HTML 和 CSS 网站。 项目链接:https://github.com/emilwallner/Screenshot-to-code-in-Keras 在未来三年内,深度学习将改变前端开发。它将会加快原型设计速度,拉低开发软件的门槛。 Tony Be
机器之心
2018/05/10
2K0
深度实践:如何用神经网络给黑白照片着色
现如今,将图片彩色化是通常用Photoshop处理的。一幅作品有时候需要用一个月的时间来着色。可能单单一张脸就需要20层的粉色、绿色和蓝色阴影才能让它看起来恰到好处。为了了解这一过程,你可以看看下面这
AiTechYun
2018/03/06
1.6K0
深度实践:如何用神经网络给黑白照片着色
深度学习第3天:CNN卷积神经网络
这张图显示了一个滤波器的某时刻的运作过程,最左边的是原图,中间是滤波器,最右边是结果,它会进行一个内积运算,图中也展示了这个过程
Nowl
2024/01/18
3030
深度学习第3天:CNN卷积神经网络
手把手搭建一个【卷积神经网络】
本文介绍卷积神经网络的入门案例,通过搭建和训练一个模型,来对10种常见的物体进行识别分类;使用到CIFAR10数据集,它包含10 类,即:“飞机”,“汽车”,“鸟”,“猫”,“鹿”, “狗”,“青蛙”,“马”,“船”,“卡车” ;共 60000 张彩色图片;通过搭建和训练卷积神经网络模型,对图像进行分类,能识别出图像是“汽车”,或“鸟”,还是其它。
一颗小树x
2021/05/12
1.5K0
手把手搭建一个【卷积神经网络】
换脸原理,使用GAN网络再造ZAO应用:可变自动编解码器基本原理
从本节开始,我们介绍一种人工智能实现无缝变脸的网络名为可变自动编解码器,英文名称:variational autoencoder。在前面章节中我们曾介绍过,很多事物看起来似乎很复杂,但只要抓住其关键变量,那就等同于抓住事物的本质,例如一个圆柱体,它的关键变量就是底部圆的半径,和高度,掌握了这两个变量的信息,我们可以轻易的将圆柱构造出来。
望月从良
2019/10/15
7980
换脸原理,使用GAN网络再造ZAO应用:可变自动编解码器基本原理
Lenet神经网络解读及其代码实现
  手写字体识别模型LeNet5诞生于1994年,是最早的卷积神经网络之一。LeNet5通过巧妙的设计,利用卷积、参数共享、池化等操作提取特征,避免了大量的计算成本,最后再使用全连接神经网络进行分类识别,这个网络也是最近大量神经网络架构的起点。虽然现在看来Lenet基本实际用处不大,而且架构现在基本也没人用了,但是可以作为神经网络架构的一个很好的入门基础。
墨明棋妙27
2022/08/24
4050
Lenet神经网络解读及其代码实现
TensorFlow快餐教程:程序员快速入门深度学习五步法
作者简介:刘子瑛,阿里巴巴操作系统框架专家;CSDN 博客专家。工作十余年,一直对数学与人工智能算法相关、新编程语言、新开发方法等相关领域保持浓厚的兴趣。乐于通过技术分享促进新技术进步。 作为一个程序员,我们可以像学习编程一样学习深度学习模型开发。我们以 Keras 为例来说明。 我们可以用 5 步 + 4 种基本元素 + 9 种基本层结构,这 5-4-9 模型来总结。 5步法: 1. 构造网络模型 2. 编译模型 3. 训练模型 4. 评估模型 5. 使用模型进行预测 4种基本元素:
用户1737318
2018/07/20
5360
基于卷积神经网络的垃圾分类
自今年7月1日起,上海市将正式实施 《上海市生活垃圾管理条例》。垃圾分类,看似是微不足道的“小事”,实则关系到13亿多人生活环境的改善,理应大力提倡。
云微
2023/02/11
9990
基于卷积神经网络的垃圾分类
拿来就能用!简单 Python 代码实现建筑识别
在人工智能的发展越来越火热的今天,其中最具有代表性的便是图像识别,其应用比比皆是,如车站的人脸识别系统,交通的智能监控车牌号系统等。卷积神经网络作为图像识别的首选算法,其对于图像的特征提取具有很好的效果,Keras 框架作为卷积神经网络的典型框架,可创建神经网络层,更容易提取图像特征,从而达到区分动物的目的,在生产实践中达到辅助的效果。
AI科技大本营
2021/02/05
1.5K0
【机器学习】神经网络的无限可能:从基础到前沿
在当今人工智能的浪潮中,神经网络作为其核心驱动力之一,正以前所未有的速度改变着我们的世界。从图像识别到自然语言处理,从自动驾驶到医疗诊断,神经网络的应用无处不在。本文旨在深入探讨神经网络的各个方面,从基础概念到最新进展,带领读者一窥其背后的奥秘与魅力。
破晓的历程
2024/08/20
3560
全网流行的黑白照片上色技术,看看飞桨开发者是如何实现的
我们都知道,有很多经典的老照片,受限于那个时代的技术,只能以黑白的形式传世。尽管黑白照片别有一番风味,但是彩色照片有时候能给人更强的代入感。本项目通过通俗易懂的方式简单实现黑白照片着色并对部分照片取得不错的着色效果。
用户1386409
2020/11/06
5990
全网流行的黑白照片上色技术,看看飞桨开发者是如何实现的
如何捕获一只彩色卓别林?黑白照片AI上色教程很友好 | 哈佛大触
方栗子 编译自 GitHub 量子位 出品 | 公众号 QbitAI △ 老照片的手动着色魔法 妈妈小时候已经有彩色照片了,不过那些照片,还是照相馆的人类手动上色的。 几十年之后,人们已经开始培育深度
量子位
2018/07/20
9420
越来越卷,教你使用Python实现卷积神经网络(CNN)
https://blog.csdn.net/weixin_44510615/article/details/117409037
润森
2022/09/22
2.9K0
越来越卷,教你使用Python实现卷积神经网络(CNN)
使用自动编解码器网络实现图片噪音去除
在前面章节中,我们一再看到,训练或使用神经网络进行预测时,我们需要把数据转换成张量。例如要把图片输入卷积网络,我们需要把图片转换成二维张量,如果要把句子输入LSTM网络,我们需要把句子中的单词转换成one-hot-encoding向量。
望月从良
2018/12/17
7750
使用神经网络解决拼图游戏
在一个排列不变性的数据上神经网络是困难的。拼图游戏就是这种类型的数据,那么神经网络能解决一个2x2的拼图游戏吗? 什么是置换不变性(Permutation Invariance)? 如果一个函数的输出
deephub
2020/08/04
1.6K0
使用神经网络解决拼图游戏
推荐阅读
相关推荐
【深度学习自动上色,数月工作几秒完成】开源神经网络图片上色技术解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档