java中是否存在内存泄漏?什么情况下才是内存泄漏?

什么是内存泄漏?

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。所以内存泄漏堆积最终会导致内存溢出。

什么是内存溢出?

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

二者之间的关系

  1. 内存泄漏堆积最终会导致内存溢出
  2. 相同点:都会导致应用程序运行出现问题,性能下降或挂起。
  3. 不同点:
    ①内存泄露是导致内存溢出的原因之一,内存泄露积累起来将导致内存溢出。
    ②内存泄露可以通过优化代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

java中是否存在内存泄漏?

Java中有垃圾回收机制,它能够将不再被使用的对象自动从内存中清除。尽管这样,java中也存在着内存泄漏。为什么呢?
首先,我们可以先明白Java中垃圾回收机制是如何进行回收:当一个内存对象失去了所有的引用之后,GC(垃圾回收机制) 就可以将其回收。也就是说java存在内存泄露的根本原因是内存对象已经不需要了,但是还仍保留了对象的引用或访问方式。比如以下几种情况:

  1. 静态集合类,如HashMap、LinkedList等等。如果这些容器为静态的,那么它们的生命周期与程序一致,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏。简单而言,长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。
public class Simple {

   Object object;

   public void method(){
       object = new Object();
   //...其他代码
   }
}

这里的object对象,其实只作用在了method()方法中,其它地方不会用到。但是,当method()方法执行结束后,object对象所分配的内存不会马上被认为是可以被释放的对象,只有在Simple类创建的对象被释放后才会被释放,严格的说,这就是一种内存泄露。解决方法就是将object作为method()方法中的局部变量

  1. 改变哈希值,当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。

  2. 各种连接,如数据库连接、网络连接和IO连接等。在对数据库进行操作的过程中,首先需要建立与数据库的连接,当不再使用时,需要调用close方法来释放与数据库的连接。只有连接被关闭后,垃圾回收器才会回收对应的对象。否则,如果在访问数据库的过程中,对Connection、Statement或ResultSet不显性地关闭,将会造成大量的对象无法被回收,从而引起内存泄漏。

  3. 变量不合理的作用域。一般而言,一个变量的定义的作用范围大于其使用范围,很有可能会造成内存泄漏。另一方面,如果没有及时地把对象设置为null,很有可能导致内存泄漏的发生。

  4. 内部类持有外部类,如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值