在Java开发工作中,考验一个程序的持续运行及高效运行,往往都会接触到内存溢出和内存泄漏问题,今天我们就来谈谈两者的发生原因及如何避免。
1.内存溢出:
1.1产生原因
比如你创建一个对象时只申请了1K的内存空间,但是创建后用户每个属性都设置的超大,远超过1K的空间,那么超过1K的数据就没地方存储,导致内存溢出。
java.lang.OutOfMemoryError,是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError。点击此处查看内存泄漏更多说明。
产生该错误的原因主要包括:
- JVM内存过小。
- 程序不严密,产生了过多的垃圾。
程序体现
一般在程序编码过程中,有以下几种情况出现均可能导致内存溢出:
- 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
- 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收。
- 代码中存在死循环或循环产生过多重复的对象实体。
- 使用的第三方软件中的BUG。
- 启动参数内存值设定的过小。
- ...........
1.2 错误提示
内存溢出的错误提示:
tomcat:java.lang.OutOfMemoryError: PermGen space
tomcat:java.lang.OutOfMemoryError: Java heap space
java:java.lang.OutOfMemoryError
1.3解决方法
1)增加JVM的内存大小
一般的java的程序都是tomcat进行运行,所以一般需要调整tomcat的启动参数。找到tomcat安装目录bin中Catalina.sh,设置JAVA_OPTS="-Xms512m -Xmx1024m -Xss1024K -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=2048m"
2)优化程序,释放垃圾
可借助dump或jvm等调优工具检查内存的相关使用情况进行分析,并检查程序避免出现以上的情况。避免死循环,防止一次载入太多的数据,提高程序健壮型及时释放。
Java内存溢出的唯一方法就是修改程序,及时地释放没用的对象,释放内存空间。
2.内存泄漏
2.1 产生原因:
是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
在Java中,内存泄漏就是存在一些被分配的对象
1)首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;
2)其次,这些对象是无用的,即程序以后不会再使用这些对象。
如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
3. 内存溢出和内存泄露的联系
内存泄露会最终会导致内存溢出。
相同点:
- 都会导致应用程序运行出现问题,性能下降或挂起。
不同点:
- 内存泄露是导致内存溢出的原因之一,内存泄露积累起来将导致内存溢出。
- 内存泄露可以通过完善代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。