引起内存泄露的原因

  • 首先内存泄露是因为一个不再被程序使用的对象或变量一直占据在内存中而引起。

Java中内存泄漏的常见场景如下:

1、长生命周期对象持有短生命周期对象的引用;
  • 比如,缓存系统,我们加载了一个对象放在缓存中,然后一直不使用这个缓存,由于缓存的对象一直被缓存引用得不到释放,就造成了内存泄漏;
  • 比如,HashMap、LinkedList等等。如果这些容器为静态的,那么它们的生命周期与程序一致,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏;
2、各种连接没有调用关闭方法
  • 如数据库连接,在对数据库进行操作的过程中,首先需要建立与数据库的连接,当不再使用时,需要调用close方法来释放与数据库的连接。只有连接被关闭后,垃圾回收器才会回收对应的对象。否则,如果在访问数据库的过程中,对Connection、Statement或ResultSet不显性地关闭,将会造成大量的对象无法被回收,从而引起内存泄漏;
3、内部类持有外部类
  • 如果一个外部类的实例对象的方法返回可一个内部类实例对象,这个内部类对象被长期引用了,即使那个外部类的实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象不会被垃圾回收,造成内存泄露;
4、改变哈希值
  • 当一个对象被存储进HashSet集合中后,就不能修改这个对象中参与计算哈希值的那个字段了,否则修改后的哈希值与最初存进HashSet中的哈希值就不同了,在这种情况下,即使在contains 方法使用该对象的当前引用作为的参数去 HashSet 集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet 集合中单独删除当前对象,造成内存泄露。