当前位置: 首页 > Linux

内存泄漏和内存溢出的区别

时间:2023-04-06 06:51:35 Linux

概念和区别1.内存泄漏(memoryleak):是指程序申请内存后,无法释放已经申请的内存空间。一次内存泄漏看似影响不大,但是内存泄漏累积起来的后果就是内存溢出。2、Outofmemory:当程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一个存储int类型数据的存储空间,你却存储了long类型数据,那么结果就是内存不够了,这时候会报错OOM,也就是所谓的内存溢出。3.两者的关系。内存泄漏的积累最终会导致内存溢出。内存溢出就是你想要的内存空间超过了系统实际分配给你的空间。这时候系统就相当于满足不了你的需求,就会报内存溢出。错误。内存泄漏是指你向系统申请分配内存以供使用(new),但使用后不归还(delete)。丢失),系统无法将其重新分配给需要它的程序。相当于用钥匙租柜子。放完东西锁上柜子后,钥匙丢了或钥匙没归还。那么结果就是这个柜子谁也用不了,也不能扔。回收商回收了,因为它找不到任何关于它的信息。内存溢出:一个盘子通过各种方法只能放4个水果,你放了5个水果,结果掉在地上不能吃。这是溢出。比如栈满了,压入栈中,势必会造成空间溢出,称为溢出。即分配的内存不足以放下数据项序列,称为内存溢出。说白了就是受不了那么多,所以会报错。4、内存泄漏的分类(按发生方式分类)频繁内存泄漏:有内存泄漏的代码会被执行多次,每次执行都会造成内存泄漏。偶发性内存泄漏:内存泄漏的代码只发生在某些特定的环境或运行过程中。频繁和偶发是相对的。对于特定的环境,零星的可能会变成规律的。所以测试环境和测试方法对于检测内存泄漏至关重要。一次性内存泄漏:发生内存泄漏的代码只会执行一次,或者由于算法缺陷,永远只会泄漏一块内存。例如,内存在类的构造函数中分配,但在析构函数中没有释放,所以内存泄漏只会发生一次。隐式内存泄漏:程序在运行过程中一直在分配内存,直到结束才释放内存。严格来说,这里不存在内存泄漏,因为最终程序释放了所有分配的内存。但是对于一个需要运行数天、数周甚至数月的服务器程序来说,不及时释放内存可能最终会耗尽系统的所有内存。因此,我们称这种内存泄漏为隐式内存泄漏。五、内存溢出的原因及解决方法:A、内存溢出的原因:1、内存中加载的数据量过大,如一次从数据库中取出的数据过多;2.集合类中有对象的引用。没有清除,使JVM无法回收;3、代码中存在死循环或循环生成过多重复对象实体;4.使用的第三方软件存在bug;5.启动参数内存值设置过小B.内存溢出解决方法:第一步修改JVM启动参数,直接增加内存。(别忘了加上-Xms,-Xmx参数。)第二步,查看错误日志,看看在“OutOfMemory”错误之前是否还有其他异常或错误。第三步,遍历并分析代码,找出可能发生内存溢出的地方。重点关注以下几点:1、检查是否存在获取数据库查询中所有数据的查询。一般来说,如果一次取10万条记录到内存中,可能会造成内存溢出。这个问题比较隐蔽。上线前,数据库中数据较少,不容易出问题。上线后,数据库中的数据较多,单次查询可能会导致内存溢出。因此,数据库查询尽量使用分页。2、检查代码中是否存在死循环或递归调用。3、检查是否存在大循环重复生成新的对象实体。4、检查是否有获取数据库查询中所有数据的查询。一般来说,如果一次取10万条记录到内存中,可能会造成内存溢出。这个问题比较隐蔽。上线前,数据库中数据较少,不容易出问题。上线后,数据库中的数据较多,单次查询可能会导致内存溢出。因此,数据库查询尽量使用分页。5、检查List、MAP等集合对象是否存在使用后未清除的问题。List、MAP等集合对象总会有对象的引用,这样这些对象就无法被GC回收。C.第四步,使用内存查看工具动态查看内存使用情况(jvisualvm)