热门标签 | 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。




推荐阅读
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 汇编语言等号伪指令解析:探究其陡峭的学习曲线
    汇编语言以其独特的特性和复杂的语法结构,一直被认为是编程领域中学习难度较高的语言之一。本文将探讨汇编语言中的等号伪指令及其对初学者带来的挑战,并结合社区反馈分析其学习曲线。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细介绍如何在VSCode中配置自定义代码片段,使其具备与IDEA相似的代码生成快捷键功能。通过具体的Java和HTML代码片段示例,展示配置步骤及效果。 ... [详细]
  • 配置Windows操作系统以确保DAW(数字音频工作站)硬件和软件的高效运行可能是一个复杂且令人沮丧的过程。本文提供了一系列专业建议,帮助你优化Windows系统,确保录音和音频处理的流畅性。 ... [详细]
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社区 版权所有