只针对JAVA来说
内存泄露本意是申请的内存空间没有被正确释放,导致后续程序里这块内存被永远占用(不可达),而且指向这块内存空间的指针不再存在时,这块内存也就永远不可达了,内存空间就这么一点点被蚕食,借用别人的比喻就是:比如有10张纸,本来一人一张,画完自己擦了还回去,别人可以继续画,现在有个坏蛋要了纸不擦不还,然后还跑了找不到人了,如此就只剩下9张纸给别人用了,这样的人多起来后,最后大家一张纸都没有了。
内存溢出是指存储的数据超出了指定空间的大小,这时数据就会越界,举例来说,常见的溢出,是指在栈空间里,分配了超过数组长度的数据,导致多出来的数据覆盖了栈空间其他位置的数据,这种情况发生时,可能会导致程序出现各种难排查的异常行为,或是被有心人利用,修改特定位置的变量数据达到溢出攻击的目的。而Java中的内存溢出,一般指【OOM:发生位置】这种Error,它更像是一种内存空间不足时发生的错误,并且也不会导致溢出攻击这种问题,举例来说,堆里能存10个数,分了11个数进去,堆就溢出了1个数,JVM会检测、避免、报告这种问题,所以虽然实际上JVM规避了内存溢出带来的问题,但在概念上来说,它确实是溢出才导致的,只是Java程序员在看到这个问题时,脑袋里的反应会是“内存不够了,咋回事,是不是又是哪个大对象没释放”之类,而不是像C程序员“我X被攻击了/程序咋写的搞溢出了”(这段是我臆想的)。同时对于Java来说,传统意义的溢出攻击也无法奏效,因为Java的数组会检查下标,对超出数组下标的赋值会报ArrayOutOfIndex错误。
而内存泄露的话,个人意见在Java里是不存在的,gc采用根搜索算法时,不可达的对象会被回收,gc是会搜索回收这些空间的,由于程序员个人问题,没用的对象不回收但可达,这种情况能不能界定为内存泄露,我觉得是个哲学问题(对象可达,但空间被占用了,对象也不再使用了),个人觉得是不能界定为内存泄露的。
答完,个人水平有限,如果有错漏希望大家随意指正指教,多谢
会的。
内存泄露是指一个对象不再使用了,但是没有被正确回收就会产生内存泄露。
尽管JVM有垃圾回收器,但是也有情况对象不会被回收的。
Java产生内存泄露的原因主要就是长生命周期对象引用短生命周期对象导致短生命周期对象无法被回收。
比如说集合中引用的对象没有清理策略,导致没有的对象一直不会被回收,从而造成内存泄露。
Java中的引用有强引用、软引用、弱引用和虚引用四种方式,一般我们声明的变量都是强引用的,可以了解下其他几种引用,即使有被引用,也会在不同的场景下被回收的。
在生产环境中tomcat内存设置不好很容易出现内存溢出。造成内存溢出是不一样的,当然处理方式也不一样。
这里根据平时遇到的情况和相关资料进行一个总结。常见的一般会有下面三种情况:
1.OutOfMemoryError: Java heap space
2.OutOfMemoryError: PermGen space
3.OutOfMemoryError: unable to create new native thread.
Tomcat内存溢出解决方案
对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。(-Xms -Xmx -XX:PermSize -XX:MaxPermSize)
最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。
引起内存不足、内存溢出的 原因 有很多种,常见的有以下几种:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.使用的第三方软件中的BUG;
5.启动参数内存值设定的过小;
如有驱动问题请咨询关注驱动人生内存溢出的解决方案 :
第一步 ,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
第二步 ,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
第三步 ,对代码进行走查和分析,找出可能发生内存溢出的位置。
重点排查以下几点:
1.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
2.检查代码中是否有死循环或递归调用。
3.检查是否有大循环重复产生新对象实体。
4.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
5.检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
第四步 ,使用内存查看工具动态查看内存使用情况。
步骤/方式1
内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,简单来讲就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
步骤/方式2
解决方法:第一步,修改JVM启动参数,直接增加内存。
步骤/方式3
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
步骤/方式4
对代码进行走查和分析,找出可能发生内存溢出的地雷位置
由于这个Handler作为内部类声明在Activity内部,普通的内部类对象隐式地保存了一个指向外部类对象的引用,所以这个Handler对象保存了一个指向Activity对象的引用。
而这个Handler对象的生命周期可能比Activity生命周期长,比如当有一个后台线程持有该Handler,别且该线程在执行一个长时间任务。
所以当该Handler没有被JVM垃圾回收器回收时,它就阻止了它引用的外部类Activity对象的回收,这里就导致了内存泄露