有很多情况会导致这一问题,像重复使用的某个结构体/对象,当再次复用时没有清理上一次使用遗留的数据、系统中存在cache,但cache的过期策略设置不得当等等。

大家好,我是小风哥,今天和大家聊一聊内存泄漏这个话题。

我之前写过好几篇关于内存的文章,在这些文章讲到内存申请时我很喜欢用停车场来做类比,内存申请就好比去停车场找停车位,找到停车位后你就可以把车停在这里。

从这个类比看什么是内存泄漏呢?内存泄漏看上去是停车场的车辆只进不出导致最终找不到停车位,从程序员的角度看就是内存只申请取不释放,如果你去问,可能有不少人认为内存泄漏就是这么回事。

然而这其实是不全面的。

申请过多内存

首先内存只申请不释放未必就是内存泄漏,有可能是你的程序的确需要申请很多内存,这是正常的,然而如果是bug导致申请了很多内存,这就是内存泄漏了,或者也有人将其称为space leak,意思是申请的内存超过了正常所需;不管是有意无意,总之在这种情况下你依然保持对这些内存的引用,因此你总可以找到这些内存并删除它们,就看你删不删。

有很多情况会导致这一问题,像重复使用的某个结构体/对象,当再次复用时没有清理上一次使用遗留的数据、系统中存在cache,但cache的过期策略设置不得当等等。

内存无法删除

另一类比较有趣的内存泄漏是说你申请了一些内存,但最终却没有什么指向它们:

void memory_leak() { char* mem = (char*)malloc(1024); // just return
} 

在这段代码中我们申请了1k内存,然而当memory_leak函数返回后你就再也不知道这段内存到底在哪里了!

用停车场的示例来说就是有些司机太过土豪,家里的车太多以至于把将车放在停车场这件事忘掉了,导致这些车根本就不会有人再开走,因此白白浪费停车位,并导致可用车位越来越少,而对于编程来说就是粗心大意的程序员申请了一些内存后最终“忘掉”了,再也不会有什么东西(变量/指针)指向这些内存,因此在这种情况下你没有办法再找到这些内存并将其删除。

内存碎片
这也算的上是一类特殊的内存泄漏,用停车场的例子来说就是两个停车位中间停靠了一辆小型老年代步车,导致尽管这两个停车位剩余的空间足够大但又恰好都没有办法再停靠一辆小汽车。

假定我们系统中宝贵的内存大小只有8字节,其中有两个字节已经分配出去了,就像这样:

现在,系统中空闲的内存是6字节,下一次的内存申请需要分配5字节,糟糕,我们已经没有办法再找到连续的5个字节大小的内存空间了,尽管全部空间的内存还有6字节,这就是所谓的内存碎片问题。

而对于内存分配器来说如果出现这种情况那么将不得不借助操作系统的帮助来扩大堆区,因此看起来我们的程序占据的内存越来越多,尽管实际上程序可能并不需要那么多内存,仅仅是因为内存碎片的原因导致一部分内存无法被再次被利用起来。

然而对于现代操作系统尤其具备虚拟内存能力的系统来说,内存碎片问题通常可能并不会和我们想象的那样严重,原因就在于分配的内存只需要在虚拟地址空间上连续而不必在物理内存上也连续,假定我们在虚拟内存地址空间需要存放“aabbccdd”这样的字符串,在虚拟地址空间上看这是连续的就像这样:

但在物理内存上可能是这样存放的:

可以看到,利用虚拟内存我们可以更加充分灵活的利用“边边角角”的物理内存,从而减少内存碎片带来的影响。

关于虚拟内存更详细的讲解你可以参考《深入理解操作系统》虚拟内存一章,关于公众号“码农的荒岛求生”并回复“操作系统”即可。

如果你的程序需要重复申请很多对象/数据/结构体,并在最后一次性全部释放,那么内存池是一个避免内存碎片不错的选择,原理在于尽管从内存池的角度看会有碎片,但当我们以内存池大小为单位从堆区中申请释放内存时,这种碎片将不复存在。

关于内存池你可以参考这篇《高性能服务器内存池是如何实现的》。

内存泄漏带来的问题

在现代操作系统中除非你的程序运行时间足够长或者申请的内存足够快足够多否则内存泄漏可能并不是什么大问题,你甚至可能都察觉不出来有内存泄漏,因为当进程运行结束后其占据的内存会被操作系统收回,在这种情况下你可能不必过于关心这个问题,但对于长时间运行的服务器端程序、数据库程序、操作系统等,内存泄漏就属于比较严重的问题了,因为这些程序必须时刻在线,任何微小的内存泄漏在时间的加持下都会非常明显。

内存持续泄漏会发生什么?

如果内存持续泄漏那么你的电脑可能会爆炸。。。这。。。当然是不可能的。

你的系统会慢到炸是有可能的。

内存的申请速度会对系统性能产生很大的影响,当系统内存不足时,内存分配器找到一块满足要求的空闲内存块将更加困难耗时更多,当程序消耗的内存超过物理内存大小时虚拟内存系统(如果有的话)开始发挥作用,将进程地址空间中不常用的一部分swap出去,此时系统性能将快速下降,表现出来的就是程序员运行变慢、卡顿。

当然,根据系统配置,像Linux系统,可能会将消耗内存很多的进程kill掉,这就是Out of Memory killer,简称oom killer。

内存泄漏检测工具

不像程序崩溃Core dump,这类问题通过debug通常能获取一些线索,但内存泄漏问题就没那么直接了,尤其对于C/C++程序来说,这时我们将不得不借助必要的工具。

那么我们该利用什么的工具来解决内存泄漏问题呢?下一篇文章将给你答案。

这个公众号里所有的文章都已经汇总在了Github上,地址https://github.com/xfenglu/everycodershouldknow ,你也可以点击左下方“阅读原文”直达,欢迎访问,求star,哈哈。

如何理解Memory leak相关推荐

  1. Android 内存管理 amp;Memory Leak amp; OOM 分析

    1.Android 流程管理&内存 Android主要应用在嵌入式设备其中.而嵌入式设备因为一些众所周知的条件限制,通常都不会有非常高的配置,特别是内存是比較有限的. 假设我们编写的代 码其中 ...

  2. Android 内存管理 Memory Leak OOM 分析

    转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...

  3. 使用LeakTracer检测android NDK C/C++代码中的memory leak

    Memory issue是C/C++开发中比较常遇到,经常带给人比较大困扰,debug起来又常常让人无从下手的一类问题,memory issue主要又分为memory leak,野指针,及其它非法访问 ...

  4. Memory Leak(内存泄漏)问题总结

    最近听了一些关于Memory Leak(内存泄漏)的seminar,感觉有些收获,所以留个记录,并share给朋友. 1 什么是Memory Leak. Memory Leak是指由于错误或不完备的代 ...

  5. LeakDiag 微软一款检测memory leak的工具

    LeakDiag是微软一款检测memory leak的工具,使用比较简单 首先去下载一个 ftp://ftp.microsoft.com/PSS/Tools/Developer%20Support%2 ...

  6. 《memory leak: stackwalk》

    <memory leak: stackwalk> /// // // StackWalk.cpp // // Author: Oleg Starodumov // // NOTE: THI ...

  7. mysql memory leak_解决memory leak问题

    应用程序注册了JDBC驱动,但当程序停止时无法注销这个驱动,tomcat为了防止内存溢出,就给强制注销了 解决: 重写了org.apache.commons.dbcp.BasicDataSource  ...

  8. This is very likely to create a memory leak.

    前言 tomcat 7.0.78 java 1.8.0_161 现象 tomcat启动过程中出现如下报错: The web application [/xx/xxx] appears to have ...

  9. 深入理解Memory Order

    深入理解Memory Order cpu 保证 cache 编程技术 lock-free wait-free Read–modify–write Compare-And-Swap(CAS) cas原理 ...

最新文章

  1. java 替换四个字节的字符 '\xF0\x9F\x98\x84\xF0\x9F)的解决方案
  2. 12C 对表分区维护的增强
  3. java任务poer_java-Powermock-模拟超级方法调用
  4. java cr_WildFly 10 CR 2发布– Java EE 7,Java 8,Hibernate 5,JavaScript支持热重载
  5. 3.15 曝光:40 亿 AI 骚扰电话和 11 家合谋者
  6. BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]
  7. java transactions数组_java里面Transaction transaction = (Transaction)(list.get(i));是什么意思...
  8. 2021,属于Golang和Gopher的全新纪元
  9. 领取免费会员活动-各大平台不定时,欢迎自取
  10. charles+https+安卓7.0+夜神模拟器,解决安卓7.0+版本https无法抓包问题
  11. 蓝桥杯-三角形 已知三点求三角形周长、面积、外心、重心
  12. 新版Space数字藏品源码+NFT数字藏品系统
  13. python随机生成一个数字_如何实现python随机生成数字?
  14. java神雕侠侣1古墓情缘游戏攻略_神雕侠侣古墓派后期攻略讲解
  15. Jackson ImmunoResearch普通羊驼血清说明书
  16. 使用JavaFX完成刽子手游戏
  17. 带你了解IT互联网行业程序员岗位有些什么类型?
  18. 面试题 05.08. 绘制直线
  19. PPmoney基于Kubernetes的DevOps实践
  20. 你离年薪50w的架构师还差多远

热门文章

  1. 高糊图片可以做什么?
  2. 360董事长周鸿祎发表全员信:疫情当前,要做好长期在家办公的准备
  3. 男人们聚会时,都聊些什么?
  4. 本、硕、博的最大区别是什么?
  5. Heartrate:一个牛逼的工具,Python执行实时可视化
  6. 18个让程序员流泪的瞬间,已笑喷,哈哈哈哈哈哈!
  7. Linux之压缩和解压缩命令
  8. celery的初次使用
  9. shell编程系列7--shell中常用的工具find、locate、which、whereis
  10. JVM解读-性能调优实例