有时候会有人问你, 内存泄漏是什么? 什么原因导致的? 如何解决?
那么内存溢出又是什么呢?
一一的解释一下:
内存溢出 out of memory: 是指程序员在申请内存时,没有足够的内存空间供其实用。比如 你申请了 2kb 的内存空间。 但是给了一个需要4kb才能存下的数据。 这就是内存溢出了。内存溢出就是, 你要求分配的内存超出了系统能够给你的内存。从而系统不能够满足需求,于是产生了溢出。
一个盘子只能装4个苹果,但是你硬是装了5个,结果掉地上了不能吃了。这就是内存溢出! 比如说栈,栈满时在做进栈的操作必定产生空间溢出,这叫做上溢,栈空时再做出栈的操作也会产生空间溢出,这叫做下溢。 就是分配的内存不足以放下数据项序列,成为内存溢出。
内存泄漏 mempry leak:是指你向系统申请分配内存进行(new)。但是使用完成之后却不归还(delete),可是你申请到的那块内存连你自己都不能访问了(有可能是因为你把它搞丢了...),这个时候 系统也不能再次的将 这块内存,分配给你需要的程序。
根据发生的方式来进行分类的话,内存泄漏可以分为4类:
1.常发性内存泄漏:发生内存泄漏的代码会被多次执行到,每次执行都会导致一块内存的泄漏。
2.偶发性内存泄漏:发生内存泄漏的代码只有在特定的环境或者操作过程下才会发生。 常发性和偶发性是相对的。 对于特定的环境,偶发性的也就编程常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
3.一次性内存泄漏:发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏。比如在类的构建函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。
4.隐士内存泄漏:程序运行过程中不停的分配内存,直到程序结束才能够释放内存。严格的说这并没有发生内存泄漏,因为程序最终释放了所申请的内存。但是对于一个服务器程序,可能需要运行 几天,几周,几月,甚至几年。如果不及时的释放内存,系统的内存资源最终都会被消耗完。so我们称这种的为隐士的内存泄漏。
对于用户来说内存泄漏没什么影响,因为他们并不在乎。而且一般的用户根本也感受不到这个东西。真正有害的是内存泄漏的堆积,因为这最终会消耗尽所有的系统资源。 从这个角度来说的话,一次性内存泄漏,其实并没有什么危害,因为他不会大量的堆积。而隐式内存泄漏则危害最大。因为较之于常发性或偶发性的内存泄漏。他更加的难以被发现。
内存泄漏 mempry leak 最终会导致 内存溢出 out of memory
内存溢出的原因以及解决方式:
1.内存中加载的数据量,过于的庞大。 比如 一次性从数据库取出50G数据。(吹牛逼 瞬间就爆炸了)
2.集合类中有对 对象的医用,使用完毕后未清空。似的解释器或编译器 不能回收。
3.代码中存在过多的 循环。 或者循环产生大量的重复的 实例化对象。
4.使用的第三方软件中 存在 BUG
5.启动参数的值设定的太小
内存溢出的解决方案:
1. 检查错误日志,查看"OutOfMemory"错误千是否有其他异常或错误。
2.对代码进行走查和分析,找出可能发生内存溢出的位置。
重点排查:
1. 检查对数据库查询中,是否有一次对数据库全部数据获取的查询。一般来说如果一次性取出10万记录到内存,就会有可能产生内存溢出。这个问题比较隐蔽。在上线之前数据会比较少,不容易出问题,上线之后数据库中数据多了。 一次查询就有可能引起内存的溢出。因此对于数据库的查询尽量采取用分页的方式。
2. 检查代码中是否有死循环或递归调用。(递归的层数,不要太深)
3. 检查是否有大量循环重复产生新对象实例。
4. 检查 容器类对象是否使用完毕后,没有被清除。(py程序员, 几乎不需要考虑。垃圾回收机制帮你解决了)
3. 使用内存查看工具动态的查看内存的使用状态。