Java中有哪些潜在的内存泄露风险

发布时间:2021-07-03 13:16 来源:未知 阅读:197 作者:admin 栏目: 数据库 欢迎投稿:712375056

 

本篇文章给大家分享的是有关Java中有哪些潜在的内存泄露风险,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

1. 内存泄露的定义

 

如果GC无法回收内存中不再使用的对象,则定义为内存有泄露

2. 未关闭的资源类

 

当我们在程序中打开一个新的流或者是新建一个网络连接的时候,JVM都会为这些资源类分配内存做缓存,常见的资源类有网络连接,数据连接以及IO流。值得注意的是,如果在业务处理中异常,则有可能导致程序不能执行关闭资源类的代码,因此最好按照下面的做法处理资源类

public void handleResource() {     try {         // open connection         // handle business     } catch (Throwable t) {         // log stack     } finally {         // close connection     } }

3. 未正确实现equals()和hashCode()

 

假如有下面的这个类

public class Person {     public String name;          public Person(String name) {         this.name = name;     } }

并且如果在程序中有下面的操作

@Test public void givenMapWhenEqualsAndHashCodeNotOverriddenThenMemoryLeak() {     Map<Person, Integer> map = new HashMap<>();     for(int i=0; i<100; i++) {         map.put(new Person("jon"), 1);     }     Assert.assertFalse(map.size() == 1); }

可以预见,这个单元测试并不能通过,原因是Person类没有实现equals方法,因此使用Object的equals方法,直接比较实体对象的地址,所以map.size()  == 100

如果我们改写Person类的代码如下所示:

public class Person {     public String name;          public Person(String name) {         this.name = name;     }          @Override     public boolean equals(Object o) {         if (o == thisreturn true;         if (!(o instanceof Person)) {             return false;         }         Person person = (Person) o;         return person.name.equals(name);     }          @Override     public int hashCode() {         int result = 17;         result = 31 * result + name.hashCode();         return result;     } }

则上文中的单元测试就可以顺利通过了,需要注意的是这个场景比较隐蔽,一定要在平时的代码中注意。

4. 非静态内部类

 

要知道,所有的非静态类别类都持有外部类的引用,因此某些情况如果引用内部类可能延长外部类的生命周期,甚至持续到进程结束都不能回收外部类的空间,这类内存溢出一般在Android程序中比

免责声明:本站发布的内容(图片、视频和文字)以原创、来自本网站内容采集于网络互联网转载等其它媒体和分享为主,内容观点不代表本网站立场,如侵犯了原作者的版权,请告知一经查实,将立刻删除涉嫌侵权内容,联系我们QQ:712375056,同时欢迎投稿传递力量。