什么是内存泄漏?

在wikipedia这样解读内存泄漏的:在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

内存不是无穷无尽的,是有限的,如果申请了,使用了,用完没有释放,那么这块内存就一直无法被重新利用,最后再申请内存就找不到空闲的了(称为out of memory,OOM),可能导致程序逻辑错误崩溃。

以下用一个简单的例子说明内存泄漏:

#include <stdio.h>
#include <stdlib.h>int main(int argc, char *argv[])
{char *p[1000];int i;for (i = 0; i < 1000; i++) {p[i] = malloc(i * 2 + 100);if (p[i])memset(p[i], 0, i * 2 + 100);}for (i = 0; i < 1000; i++) {printf("%p\n", p[i]);}return 0;
}

上面的程序malloc申请的内存直至退出都没有被释放,这个就是内存泄漏了。

分类

1.内存泄漏可以根据发生的方式来分类:

常发性泄漏 

故障代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

偶发性泄漏 

故障代码只有在特定场景或操作过程下才会被执行。常发性和偶发性是相对的。对于特定场景,偶发性的也许就变成了常发性的。所以测试场景和方法对检测内存泄漏至关重要。

一次性泄漏 

故障代码只会被执行一次或者由于逻辑的缺陷导致只有一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存。

隐式泄漏 

程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但对于daemon或需要长时间运行的程序来讲,不及时释放可能最终耗尽所有内存。

2.还可以根据泄漏类型来分类:

未引用泄漏 

这些泄漏点,已无任何指针指向,因此无法被找到,永远无法被释放。native/kernel有这类问题,而java无此类问题,因为没被找到的,都可以gc。引用泄漏 可以被找到,等于隐式泄漏。

引用泄漏

像是缓存没有控制上限而导致耗尽内存。如果控制的好,则没问题,比如kernel里的slub也有per cpu缓存。java也有这种问题存在。另外不同的软件层都有可能存在内存泄漏:kernel层、native层和java层。不同的软件层泄漏的原理都差不多。

危害

内存泄漏是较难检测的异常之一,除了常发性泄漏,其他都是难以检查到的。从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为用户无法感觉到内存泄漏的存在,除非泄漏大量内存或一直累积直至消耗光内存,这时就有各种明显表现:

  • 性能渐渐变差,因为要做各种内存回收工作。

  • 直接出现逻辑错误崩溃,没有做好异常处理(error handling)。

  • 本身没有问题,却引起其他程序异常。既然内存泄漏这么难处理,那么是否有办法自动回收,不需要编程人员管理申请的内存呢?有的,java语言就有内存回收机制(垃圾回收,gc)。

不过即使用java编写的程序也可能出现泄漏,后面会讲解java内存泄漏的原理和调试方法。

通用的调试方法

需要对每一块申请的内存做标记,记录调用栈等信息,然后监控内存用量信息,感觉已经超出正常的内存用量很多时(相差不大时不见得能查到问题),提取这些信息,然后分析信息,找出可能的泄漏点,检查代码,分析逻辑,修复问题。


  回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

requests库之处理响应

response对象&#xff1a; http状态码 利用response把流存储成图片或者文件 一个下载图片的实例 import requestsdef download_pic():#headers {User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36…

持久化概述

持久化概述 文章目录持久化概述对象持久化扁平文件pickleshelve数据库ORM扁平文件保留类型还原eval字符串转列表&#xff08;不带&#xff0c;&#xff09;![](https://img-blog.csdnimg.cn/20200201211443931.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,sha…

五分钟读懂TCP 协议

TCP 是互联网核心协议之一&#xff0c;本文介绍它的基础知识。一、TCP 协议的作用互联网由一整套协议构成。TCP 只是其中的一层&#xff0c;有着自己的分工。&#xff08;图片说明&#xff1a;TCP 是以太网协议和 IP 协议的上层协议&#xff0c;也是应用层协议的下层协议。&…

正则表达

文章目录正则表达数据验证字面值\d查数字^\w特殊符号匹配规则.除|n所有字符\d查数字\D非数字![在这里插入图片描述](https://img-blog.csdnimg.cn/20200203213049246.png)\s空白字符![在这里插入图片描述](https://img-blog.csdnimg.cn/20200203213145246.png)\S非空白字符![在…

《从三月开始……》

很多时候&#xff0c;我们对不同现状有所不满——对无法冲破的工作瓶颈不满对久不增长的收入不满对久不下降的体重不满对无法提高的学分不满对没有进展的关系不满……似乎总有某个方面的不顺给我们带来烦恼为此&#xff0c;我们也做了“努力”——我们通过各种渠道和平台去查阅…

从未知到2019年的文章汇总

2018年下半年我正式把这个遗弃了很久的微信号运营起来&#xff0c;2019年应该是比较正式的一年&#xff0c;也是成长最快的一年。从开始捣鼓微信公众号到现在&#xff0c;我写了很多东西。这篇文章把之前写过的&#xff0c;不管是好的&#xff0c;还是不好的&#xff0c;都整理…

Binder远程转本地

前言在[031]Binder线程栈复用中&#xff0c;我们说到Binder驱动通过“线程栈复用”减少线程数&#xff0c;我们来讲一讲另外一个机制“远程转本地”&#xff0c;将远程Binder调用转化成本地方法调用。一、写个Demointerface IServiceB {void sendMsg(String msg); }1.1 Client…

存储对手机性能的影响

前言几年以前&#xff0c;我被派去厦门上门去分析一个用户的手机卡顿问题&#xff0c;该用户的手机经常莫名无响应&#xff0c;刷机&#xff0c;恢复出厂都没有用&#xff0c;经过一通分析&#xff0c;原来该用户从熟人店里买到了一张盗版的SD卡&#xff08;这年头坑的就是朋友…

进阶攻略|前端最全的框架总结

前端的技术日渐更新&#xff0c;最近得空&#xff0c;花了一上午的时间&#xff0c;将前端常见的UI框架总结了一下&#xff0c;在开发的过程之中&#xff0c;有了这些&#xff0c;不断能够提高自己的工作效率&#xff0c;还可以在工作之余了解更多。希望大家喜欢。1.Layui官方网…

你知道char *s和char s[]的区别吗?

在一个夜深人静的晚上&#xff0c;有一个读者给我发了一个C语言题目。他问我&#xff0c;发哥&#xff0c;帮我看看这个代码有什么问题。我看了代码之后&#xff0c;心里一阵恐慌。我自认为我不是C语言高手。但我确实是一个喜欢解决问题的男人。就是在这样的背景驱使下&#xf…

上Google Adsense个人的一点体验

最近我想开通一个Google Adsense帐号&#xff0c;因为以前注册过一个Google帐号&#xff0c;所以我以为两个是可以共通的&#xff0c;因为很久没上Google帐号&#xff0c;我记不太清密码了&#xff0c;所以我先是登录了Google&#xff0c;登上去了&#xff0c;密码没记错。然后…

通俗易懂,嵌入式Linux驱动基础

前言上一篇分享的&#xff1a;《从单片机工程师的角度看嵌入式Linux》中有简单提到Linux的三大类驱动&#xff1a;我们学习编程的时候都会从hello程序开始。同样的&#xff0c;学习Linux驱动我们也从最简单的hello驱动学起。驱动层和应用层 还记得实习那会儿我第一次接触嵌入式…

记,我在深圳买房

今天晚上&#xff0c;有点时间&#xff0c;把这次买房的经历写下来。我并不是想炫耀&#xff0c;也不是想说明什么&#xff0c;只是为了记录自己的生活。这是对自己的一个阶段性总结&#xff0c;也希望自己的意见和想法对读者们有些帮助。再者&#xff0c;凭自己的努力&#xf…

tif 高程_使用ArcGIS提取高程点

地球表面形状的最常见数字化数据便是基于像元的数字高程模型(DEM)&#xff0c;该数据可用作量化地表特征的输入。DEM属于一种连续表面的栅格制图表达&#xff0c;通常参考真实的地球表面&#xff0c;有的时候除了需要DEM还需要高程点&#xff0c;这里讲解一下如何使用ArcGIS从D…

你试试用心呼吸

我曾经历过掉水里&#xff0c;两次。第一次&#xff0c;是在水上乐园&#xff0c;不会游泳的我&#xff0c;从高滑梯上头朝下扎到水中。一下子&#xff0c;就感觉呼吸不了&#xff0c;非常惊恐&#xff0c;然后有人&#xff08;救生员&#xff09;揽住了我&#xff0c;我非常惊…

Git安装及密钥的生成并上传本地文件到GitHub上

之前用的GitHub&#xff0c;不太熟练&#xff0c;一直在上传的过程中遇到了一些问题&#xff0c;看了网上诸多教程&#xff0c;总觉得很乱&#xff0c;特参考一些资料&#xff0c;总结了一篇完整的操作步骤&#xff0c;从下载安装到上传文件&#xff0c;亲测有效1.下载Git软件&…

声明为数组定义为指针,声明为指针定义为数组

导语在这里我们做种强调的是在两个文件中&#xff0c;定义为数组声明为指针和定义为指声明为数组的这辆中情况。那么我们就需要两个源文件test.c和main.c。定义为数组&#xff0c;声明为指针test.cchar arr[] "abcdef";main.c#define _CRT_SECURE_NO_WARNINGS 1 #in…

python selenium环境配置Firefox和Chrome

1、下载Selenium库&#xff0c;可以使用pip install selenium https://pypi.python.org/pypi/selenium/ 2、下载驱动 Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads Firefox: https://github.com/mozilla/geckodriver/releases 3、配置环境变量 需要…

BUG_ON()、panic()、dump_stack()几种内核调试手段

Linux内核有一些方法可以用来方便标记bug&#xff0c;提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。当被调用的时候&#xff0c;它们会引发oops&#xff0c;导致栈的回溯和错误信息的打印。这些声明会导致 oops跟硬件的体系结构是相关的。大部分体系结构把BUG()和BUG_O…

wordvba编程代码大全_这几本基础编程书籍一定要看

程序员书库(ID&#xff1a;OpenSourceTop) 编译书单来自&#xff1a;https://simpleprogrammer.com/best-programming-books-2019/关于程序员类的技术书籍有很多&#xff0c;但是往往没有时间阅读&#xff0c;下面的这些书籍&#xff0c;由John Sonmez精选&#xff0c;可以帮助…