1、什么是内存溢出?
Out Of Memory(OOM):指程序在申请内存时,没有足够的内存空间;
例如:申请了一个Integer,但是要放一个long才能存放的数据;
2、内存泄漏?
无用的对象持续占有内存,从而造成内存空间的浪费;
程序申请内存使用完成之后,并没有释放内存空间,从而造成的内存的浪费成为内存泄漏;一次内存泄漏可以忽略,但是内存泄漏的堆积后果很严重;
3、内存溢出与内存泄漏的关系?
大量的内存泄漏最终会导致内存溢出;
4、内存泄漏的分类有哪些?
分类:常发性内存泄漏、偶发性内存泄漏、一次性内存泄漏、隐式内存泄漏;
(1)常发性内存泄漏:发生内存泄漏的代码多次执行,每次执行都会导致一块内存被泄漏;
(2)偶发性内存泄漏:发生内存泄漏的代码只有在某些特定的环境或操作过程才会发生;
ps:偶发性与常发性相互对立,但是对于特定的环境偶发性也许就变成了常发性;
(3)一次性内存泄漏:内存泄漏的代码只会执行一次,或者由于算法的缺陷,导致总是有一块内存发生泄漏;
例如:在构造函数中分配内存,在析构函数中却没有释放内存;
析构函数:与构造函数相反,当对象结束生命周期时,如果所在的函数已经调用完毕,系统会自动执行析构函数(java中用不到析构函数,因为java中有GC)
(4)隐式内存泄漏:在程序运行的过程中不断地分配内存,直到结束时才会释放;严格来说其不应该改属于内存泄漏,但是对于一个长期运行的函数来说,不及时释放内存也可能会导致内存溢出;
5、内存泄漏的隐患?
从用户的角度来说,内存泄漏本身不会产生什么危害,作为一个用户,根本感觉不到内存泄漏;真正有危害的是内存泄漏的堆积,这会导致消耗系统的内存;
以内存泄漏堆积的角度来说,一次性内存泄漏并没有太大的危害,因为其不会堆积,而隐式内存泄漏危害性最大,因为其较之于常发性、偶发性内存泄漏,更难被检测;
6、内存泄漏的原因?
(1)内存中加载的数据量过大,如一次性从数据库取出过多的数据;
(2)集合类中有对对象的引用,但是是用完之后并未清空,使得JVM不回收对象,在内存中堆积;
(3)代码中的循环体或者死循环产生过多的重复的对象;
(4)使用的第三方软件中的bug;
(5)启动参数内存设置太小;
7、内存泄漏的解决办法?
(1)修改JVM启动参数,增加内存;
(2)对代码进行走查和分析,找出可能导致内存溢出的问题代码
例如:1>、数据库的查询语句部分,是否没有使用分页查询;
2>、检查代码中是否有死循环或者递归调用,循环体会产生重复的对象;
3>、检查集合是用完之后是否清除;
(3)实用工具动态查看内存使用情况;
8、具体的在JAVA中可能导致内存泄漏的原因?
ps:这一块主要是针对具体的问题
(1)静态集合类引起的内存泄漏;因为静态变量的生命周期与应用程序一致,因此在程序运行过程中他们所占有的内存无论是否使用,使一直处于占用的情况;
(2)监听器:释放对象的时候没有删除监听器,从而增加了内存泄漏的机会;
(3)各种连接:例如数据库的连接、网络连接、IO连接等除非显示的调用close方法,否则是不会GC的;
(4)单例模式:如果单例的对象持有外部对象的引用,那么这个外部对象不能被JVM正常的回收(会以静态变量的形式存储在内存中);
(5)当集合里的对象的属性被修改后,调用remove方法时不起作用;