热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c++内存管理_C/C++内存管理概述

CC赋予程序员管理内存的自由,是CC语言特色,虽然这引入了复杂度和危险性,但另一方面,它也增加了控制力和灵活性,

C/C++赋予程序员管理内存的自由,是C/C++语言特色,虽然这引入了复杂度和危险性,但另一方面,它也增加了控制力和灵活性,是C/C++独特之处,亦是强大之处。

动态内存分配器

libc是c语言的标准程序库,glibc是c标准程序库在linux系统下的一个实现。动态内存分配器(例如glibc ptmalloc)是介于操作系统和应用程序之间的一个程序库,从kernel程序员的视角看来,它属于应用程序库,因为free掉的内存不一定真正返还系统,而应用程序员看来,它又属于偏系统级程序,因为free掉之后,应用程序似乎已经完成了归还。

虚拟存储

操作系统管理物理内存,运行在操作系统上的应用程序,拥有独立的虚拟地址空间,操作系统提供从虚拟地址到物理地址之间的映射,这种转换是自动的,需要硬件(寄存器)和软件(页表)配合完成,虚拟内存是计算机的一个核心概念,基于虚拟内存而不是物理内存,使得运行在单机上的多个进程之间共享存储变得可能。我们用c/c++开发应用,使用的地址都是虚拟地址,如果访问的虚拟地址不在内存里,则产生缺页中断,操作系统会自动换页,而这个过程是有成本的,惩罚还不低,所以,我们应该了解和利用局部性,这对指令和数据同样有效。

linux进程的虚拟地址空间

下面的两张图描绘了linux进程的虚拟地址空间,理解这个很重要。

66814f667fbc388369b494b99819f044.png

cd8a4c84379933be1d2bd091b6a535b5.png

CACHE

CPU、寄存器、(多级)缓存、内存、磁盘IO各级之间的速度至少相差一个量级,没有什么是cache解决不了的。

我们应该利用局部性,编写和选择局部性好的算法,比如基于有序数组的二分查找往往比rbtree更快。

应用程序内存管理

用c/c++编写应用程序,经常接管动态内存分配和回收,主要基于以下几方面的考虑。

  1. 快,希望动态内存的请求能够得到迅速满足,动态内存分配器吞吐率越大越好。

  2. 省,减少内存碎片,包括内碎片(chunk块内部填充)和外碎片,有更好的内存利用率。快和省往往是此消彼长的,内存管理常需平衡折中。

  3. 稳,期望更好的安全保障,比如避免泄漏、悬垂指针等。

基于以上需求,形形色色的内存管理技巧被发掘出来。

比如nginx基于pool的技术,让每个request从单独的pool对象里分配内存,pool通过移动指针(快)满足动态内存请求,request处理过程中不需要为每个分配的chunk做释放动作,只需要在request处理完成阶段释放pool,从而释放过程中申请的每个chunk,从而拥有更好的安全性。

小对象分配,如果void *p = malloc(1)分配一个字节,实际上因为有首尾部和填充,所以实际上消耗远远大于一个字节,这体现在用malloc_usable_size(p)返回值远大于1字节。有效载荷跟实际占用的比值应该是越大越好,而小对象有效载荷比较小,所以有必要优化它,这对于频繁且大量分配小对象的应用程序是有效的,有很多针对小对象的分配优化方法,比如经典的《C++设计新思维》提到的小对象分配器。

对象池,针对一类对象的专用分配器,因为libc的动态内存分配器是为通用目的而设计的,它在最广泛情况下表现良好,但不是每种情况都表现最好,所以针对特定场景和需求而专门设计内存分配策略,是有效的。如果应用程序,有一类对象,最多只分配1000个,便可以用这类对象池,它几乎同时满足了快、省、稳的要求。

预分配、有些业务场景,会在服务启动时候把内存都分配好,运行过程中,不再动态申请,这在游戏服务器等业务中经常出现,初听有些奇怪,实际上,它也带来一些好处,比如程序运行过程中,你不用担心OOM的问题,因为理论上它的内存占用量是直线,而且基于预分配的策略,内存泄漏的问题也会少很多。

语言和工具支持

c语言支持hook malloc、free、realloc等接口,这样你可以从比较低的层次干预和统计内存分配。

c++支持operator new/new[]、operator delete/delete[]、以及类的operator new/delete重载。

c++的标准库容器,比如vector、list、map等,都支持传入自定义allocator,你可以接管内存配置,而不限于默认分配器。

COW(Copy On Write)写时拷贝是一项能节省拷贝的技术,fork出来的进程也用到了cow,如果要全量拷贝,那fork的返回会延迟很多。

为了防止内存泄漏,有时候会借助RAII技术。

引用计数是实现智能指针的关键技术,需要区分弱引用和强引用,以及shared和unique,所有权的概念。

ptmalloc可以开启一些统计选项,这可以为排错提供帮助。

libc的动态内存分配器默认是ptmalloc,你也可以用google的tcmalloc,以及jemalloc等动态内存分配器替换。

监控和查找内存泄漏问题,你可以借助valgrind工具,不过valgrind对代码有要求,只有符合它期望的程序才能valgrind干净,不然误报会比较多。

内存拷贝是我们应该竭力减少的,不做任何多余的拷贝,很多程序profiling会发现,内存、字符串相关的函数经常出现在top list。




推荐阅读
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 利用决策树预测NBA比赛胜负的Python数据挖掘实践
    本文通过使用2013-14赛季NBA赛程与结果数据集以及2013年NBA排名数据,结合《Python数据挖掘入门与实践》一书中的方法,展示如何应用决策树算法进行比赛胜负预测。我们将详细讲解数据预处理、特征工程及模型评估等关键步骤。 ... [详细]
  • 主板IO用W83627THG,用VC如何取得CPU温度,系统温度,CPU风扇转速,VBat的电压. ... [详细]
  • 优化Flask应用的并发处理:解决Mysql连接过多问题
    本文探讨了在Flask应用中通过优化后端架构来应对高并发请求,特别是针对Mysql 'too many connections' 错误的解决方案。我们将介绍如何利用Redis缓存、Gunicorn多进程和Celery异步任务队列来提升系统的性能和稳定性。 ... [详细]
  • 访问一个网页的全过程
    准备:DHCPUDPIP和以太网启动主机,用一根以太网电缆连接到学校的以太网交换机,交换机又与学校的路由器相连.学校的这台路由器与一个ISP链接,此ISP(Intern ... [详细]
  • 对于许多初学者而言,遇到总线错误(bus error)或段错误(segmentation fault/core dump)是极其令人困扰的。本文详细探讨了这两种错误的成因、表现形式及解决方法,并提供了实用的调试技巧。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 精选多款高效实用软件及工具推荐
    本文介绍并推荐多款高效实用的软件和工具,涵盖系统优化、网络加速、多媒体处理等多个领域,并提供安全可靠的下载途径。 ... [详细]
  • CentOS 7.6环境下Prometheus与Grafana的集成部署指南
    本文旨在提供一套详细的步骤,指导读者如何在CentOS 7.6操作系统上成功安装和配置Prometheus 2.17.1及Grafana 6.7.2-1,实现高效的数据监控与可视化。 ... [详细]
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 探讨在PHP开发中,如何选择使用Cookie或数据库来优化网站性能,特别是在处理用户保存的搜索结果时。 ... [详细]
  • ElasticSearch 集群监控与优化
    本文详细介绍了如何有效地监控 ElasticSearch 集群,涵盖了关键性能指标、集群健康状况、统计信息以及内存和垃圾回收的监控方法。 ... [详细]
  • 本文详细介绍了如何在Android 4.4及以上版本中配置WebView以实现内容的自动高度调整和屏幕适配,确保中文显示正常,并提供代码示例。 ... [详细]
  • 本文详细对比了Windows 7家庭高级版与旗舰版之间的主要区别,包括技术支持期限、硬件兼容性及特色功能等方面。 ... [详细]
author-avatar
mobiledu2502889415
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有