电脑内存泄露

电脑内存泄露原因

1、操作系统自身运行时,就要占用可观内存空间。用户虽然运行的应用程序较少,但有内存吃货的应用在运行,内存资源消耗也会很明显的。  2、厂商预装的操作系统、应用软件中,有些不需要开机运行的服务程序被较多地加载,也是占用率高的原因之一。也就是说,一些用户用不到的程序都在后台远行,形成了内存占用率高现象。可用系统优化工具清理它们,给系统减赋。  3、用户运行了大任务量应用程序,重负之下,会耗用较多内存。如浏览器中打开一、二十个窗口,看高清电影,玩大型游戏,或进行视频编辑等操作等。这些都是高负荷任务,内存占用量会暴增。还有些人喜欢同时开启多项任务,也是占用率高的原因之一。  4、举个例子。就象糖尿病患者一样,吃的越多,血糖就越高,危险就来了;按医嘱少吃点,血糖就下来了。电脑的效率,不是应用开得多它就高,而是要依据硬件配置情况,适当开启一定量的应用,给系统多留一些动态内存缓存数据,才能真正提高系统运行效率。


电脑内存泄漏

这个得看进程。另外,如果是开机或偶尔这样,那是因为开机启动程序比较多,既有系统的,也有应用软件的,特别是安全软件,开机过程中要进行各种检测,内存和CPU占比都较大,完成检测后就降下来了。此外,安全软件升级时或打系统补丁时,这种情况也有。都是正常现象。


电脑内存泄露原因分析

严格意义上的内存泄露的原因只有一种:没有释放向系统申请的内存,因为不申请内存,就谈不上什么泄露,搞清楚内存泄露的原因,应当从汇编语言的角度考虑问题。

当然没有释放内存的原因是多种的:

有可能是你自己代码写的不好,忘记了释放自己代码里申请的内存,

也有可能是你使用了一个写的不好的库,库本身有问题,这里说的库不仅仅是第三方库,甚至于各种语言的运行时库也有可能出现(再高的人都免不了出BUG),还甚至于操作系统的库,因为操作系统的BUG也多的很(当然系统一般情况不会出现这些低级的错误)。


电脑内存泄露原因是什么

电脑的内存条能不能恢复出数据,完全没必要担心数据泄露。电脑硬盘、手机内存卡等等才能恢复数据。

内存条的作用是缓存,只做转接桥梁的作用。

硬盘存放数据。内存条是ram,随机存储器,断电后自动释放内存,除非不断电,软件不关闭可以,否则不行。


内存泄漏原因以及解决办法

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

PS:众所周知java有一种内存自动回收机制,所以大家可以放心大胆的用申请,去用对象,但是,有些时候,如果代码逻辑上出现问题,就会造成无法回收了,也就是说你不能再使用这些内存了,这部分内存就算是泄露出去的啦,而内存泄露会最终会导致内存溢出!

大家都知道虚拟机针对每一个应用都会分配给一定量的内存,当你的请求量超过这个值的时候,就是内存溢出。


电脑内存泄露原因有哪些

看着几个应用的内存并不高,应该是后台应用太多造成的。试着单击选项卡排个序,找找内存高的应用,比如超过20MB的(警告:不要管系统进程)如果没有多少的话,说明死内存(内存泄漏,没有释放的固定分配内存)太多了,而且应该是来自机器而不是系统,否则开机会重置的。最后实在各项都正常的办法,把内存卡拿出来看看,是不是硬件出问题了。


电脑内存泄露如何解决

除非你卡里存着涉嫌保密协议的东西(再说这种东西你拿内存卡存本身就涉嫌违规了吧),一般不用担心。

为什么?

内存卡返修都是直接给你换的新卡。具体情况我不是做这个的,但个人猜测应该是维修一张卡的成本远比批量制造出来的一张卡的成本要高,TF卡基本都是一次性封装。所以无论哪个厂商都是给你换新的。保修协议也有不保数据的相关条例。

既然不修,那么卡到哪里去了呢?无非就是拆解出芯片重新利用或者直接报废了呗。

关于数据,如果仔细想想的话,一般是没有问题的,为啥?返修的卡那么多,谁会去一张张卡开来看里面有什么东西?拆解重新利用,也都是大批量操作,有没有电脑处理还说不定呢。

假设有这么一个岗位,你在做,每天对着成百上千的返修卡,你会一张张拿来连电脑查看么?何况修复卡势必要拆解,拆解之后还要重做固件等等,你想看闪存的东西还要用单独的读写工具。在成千上万张返修的卡里单独挑出你一张卡还要各种巧合遇到有人拿来读里面的数据,这概率你可以去买彩票了。


导致内存泄漏的原因

共享内存(Shared Memory)一般指的是操作系统提供的一种用于进程间通信的方式,你说的那东西叫内存池(Memory Pool),比如

Nginx

就使用了内存池。

内存池的主要作用不是防止内存泄漏,反而是内存池不容易通过valgrind这种工具检查内存泄漏,比如你从内存池里取出一块内存,然后忘记还给内存池了,这不就是内存泄漏吗?(还是说题主是不是对内存泄漏有什么误会?)

内存池的主要优点是在小块内存分配次数过多的时候避免频繁地向操作系统申请内存,大块内存就,小块内存就直接从内存池里取。前者是将物理内存转换成虚拟内存返回给用户需要陷入内核态,后者只是通过算法计算出一个指针并返回,在用户态做的。

杜绝内存泄漏(以及资源泄露),一方面是良好的编程习惯(比如C的goto清理分支,C++的RAII),另一方面是学会使用valgrind等内存泄漏检测工具。否则还是积极拥抱GC比较好,虽然对于某个资源类你调用了但是忘记了一样会内存泄露。


如何发现内存泄露

您好,很高兴为您解答。

怎样检测内存泄露:

检测内存泄漏的关键是要能截获住对分配内存和释放内存的函数的调用。截获住这两个函数,我们就能跟踪每一块内存的生命周期,比如,每当成功的分配一块内存后,就把它的指针加入一个全局的list中;每当释放一块内存,再把它的指针从list中删除。这样,当程序结束的时候,list中剩余的指针就是指向那些没有被释放的内存。这里只是简单的描述了检测内存泄漏的基本原理,详细的算法可以参见SteveMaguire的>。

如果要检测堆内存的泄漏,那么需要截获住malloc/realloc/free和new/delete就可以了(其实new/delete最终也是用malloc/free的,所以只要截获前面一组即可)。对于其他的泄漏,可以采用类似的方法,截获住相应的分配和释放函数。比如,要检测BSTR的泄漏,就需要截获SysAllocString/SysFreeString;要检测HMENU的泄漏,就需要截获CreateMenu/DestroyMenu。(有的资源的分配函数有多个,释放函数只有一个,比如,SysAllocStringLen也可以用来分配BSTR,这时就需要截获多个分配函数)

在Windows平台下,检测内存泄漏的工具常用的一般有三种,MSC-RuntimeLibrary内建的检测功能;外挂式的检测工具,诸如,Purify,BoundsChecker等;利用WindowsNT自带的PerformanceMonitor。这三种工具各有优缺点,MSC-RuntimeLibrary虽然功能上较之外挂式的工具要弱,但是它是免费的;PerformanceMonitor虽然无法标示出发生问题的代码,但是它能检测出隐式的内存泄漏的存在,这是其他两类工具无能为力的地方。


内存泄露异常

闭包内存泄漏表现为汽车加油门有震动声音,原因和解决方法如下

3、发动机缺缸,发动机缺缸是代表发动机有一个,或者是几个气缸没有正常工作,一般常见的表现是汽车的动力不足,并且排气管抖动也很厉害,可以清楚听到发动机油嗡嗡的响声。

4、机油问题,如果汽车缺少机油,或者是机油的粘度很大,此时发动机加油门的时候,也会产生嗡嗡的响声。


常见的内存泄露

要想检测内存泄漏,就必须对程序中的内存分配和释放情况进行记录,所能够采取的办法就是重载所有形式的operator new 和 operator delete,截获 new operator 和 delete operator 执行过程中的内存操作信息。下面列出的就是重载形式

void* operator new( size_t nSize, char* pszFileName, int nLineNum )

void* operator new[]( size_t nSize, char* pszFileName, int nLineNum )

void operator delete( void *ptr )

void operator delete[]( void *ptr )

我们为 operator new 定义了一个新的版本,除了必须的 size_t nSize 参数外,还增加了文件名和行号,这里的文件名和行号就是这次 new operator 操作符被调用时所在的文件名和行号,这个信息将在发现内存泄漏时输出,以帮助用户定位泄漏具体位置。对于 operator delete,因为无法为之定义新的版本,我们直接覆盖了全局的 operator delete 的两个版本。

在重载的 operator new 函数版本中,我们将调用全局的 operator new 的相应的版本并将相应的 size_t 参数传入,而后,我们将全局 operator new 返回的指针值以及该次分配所在的文件名和行号信息记录下来,这里所采用的数据结构是一个 STL 的 map,以指针值为 key 值。当 operator delete 被调用时,如果调用方式正确的话(调用方式不正确的情况将在后面详细描述),我们就能以传入的指针值在 map 中找到相应的数据项并将之删除,而后调用 free 将指针所指向的内存块释放。当程序退出的时候,map 中的剩余的数据项就是我们企图检测的内存泄漏信息--已经在堆上分配但是尚未释放的分配信息。

以上就是内存检测实现的基本原理,现在还有两个基本问题没有解决:

1)如何取得内存分配代码所在的文件名和行号,并让 new operator 将之传递给我们重载的 operator new。

2)我们何时创建用于存储内存数据的 map 数据结构,如何管理,何时打印内存泄漏信息。

先解决问题1。首先我们可以利用 C 的预编译宏 __FILE__ 和 __LINE__,这两个宏将在编译时在指定位置展开为该文件的文件名和该行的行号。而后我们需要将缺省的全局 new operator 替换为我们自定义的能够传入文件名和行号的版本,我们在子系统头文件 MemRecord.h 中定义:

#define DEBUG_NEW new(__FILE__, __LINE__ )

而后在所有需要使用内存检测的客户程序的所有的 cpp 文件的开头加入

#include "MemRecord.h"

#define new DEBUG_NEW

就可以将客户源文件中的对于全局缺省的 new operator 的调用替换为 new (__FILE__,__LINE__) 调用,而该形式的new operator将调用我们的operator new (size_t nSize, char* pszFileName, int nLineNum),其中 nSize 是由 new operator 计算并传入的,而 new 调用点的文件名和行号是由我们自定义版本的 new operator 传入的。我们建议在所有用户自己的源代码文件中都加入上述宏,如果有的文件中使用内存检测子系统而有的没有,则子系统将可能因无法监控整个系统而输出一些泄漏警告。

再说第二个问题。我们用于管理客户信息的这个 map 必须在客户程序第一次调用 new operator 或者 delete operator 之前被创建,而且在最后一个 new operator 和 delete operator 调用之后进行泄漏信息的打印,也就是说它需要先于客户程序而出生,而在客户程序退出之后进行分析。能够包容客户程序生命周期的确有一人--全局对象(appMemory)。我们可以设计一个类来封装这个 map 以及这对它的插入删除操作,然后构造这个类的一个全局对象(appMemory),在全局对象(appMemory)的构造函数中创建并初始化这个数据结构,而在其析构函数中对数据结构中剩余数据进行分析和输出。Operator new 中将调用这个全局对象(appMemory)的 insert 接口将指针、文件名、行号、内存块大小等信息以指针值为 key 记录到 map 中,在 operator delete 中调用 erase 接口将对应指针值的 map 中的数据项删除,注意不要忘了对 map 的访问需要进行互斥同步,因为同一时间可能会有多个线程进行堆上的内存操作。

好啦,内存检测的基本功能已经具备了。但是不要忘了,我们为了检测内存泄漏,在全局的 operator new 增加了一层间接性,同时为了保证对数据结构的安全访问增加了互斥,这些都会降低程序运行的效率。因此我们需要让用户能够方便的 enable 和 disable 这个内存检测功能,毕竟内存泄漏的检测应该在程序的调试和测试阶段完成。我们可以使用条件编译的特性,在用户被检测文件中使用如下宏定义:

#include "MemRecord.h"

#if defined( MEM_DEBUG )

#define new DEBUG_NEW

#endif

当用户需要使用内存检测时,可以使用如下命令对被检测文件进行编译

g++ -c -DMEM_DEBUG xxxxxx.cpp

就可以 enable 内存检测功能,而用户程序正式发布时,可以去掉 -DMEM_DEBUG 编译开关来 disable 内存检测功能,消除内存检测带来的效率影响。


赞 (6)
打赏 微信扫一扫 微信扫一扫

相关推荐