【你问我答】JVM内存泄露有哪几种常用情景?

问题描述:

JVM内存泄露有哪几种常用情景?

回答有奖:

选取一位认真回答问题的牛友,赠送200牛币!
▶回答尽量有自己的思考,不要单纯的只是复制粘贴定理定义,或者他人blog哦~

你问我答问题汇总:点击进入
关注你问我答栏目:点击关注

你问我答 - 答问题,成大佬,拿牛币!
你问我答是牛客新栏目,每周1期几个面试中真实遇到的问题,
牛友在问题贴下留下自己的知识,经验与见解,
帮助更多牛友了解更多技术相关知识!
#悬赏##Java工程师##面试题目#
全部评论
1、静态集合类引起内存泄漏   像HashMap、LinkedList、Vector等的使用最容易出现内存泄露。如果这些容器为静态的,那么它们的生命周期与程序一致,容器中的对象Object在程序结束之前将不能被释放,因为它们一直被Vector等引用着,造成内存泄漏。长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。 2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。 3、***     在释放对象的时候却没有去删除这些***,增加了内存泄漏的机会。 4、各种连接   比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接。在对数据库进行操作的过程中,首先需要建立与数据库的连接,当不再使用时,需要显式的调用close方法来释放与数据库的连接,否则是不会自动被GC回收的。只有连接被关闭后,垃圾回收器才会回收对应的对象。否则,如果在访问数据库的过程中,对Connection、Statement或ResultSet不显性地关闭,将会造成大量的对象无法被回收,造成内存泄漏。 5、内部类和外部模块的引用    如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,造成内存泄露。 6、单例模式   不正确使用单例模式。单例对象在初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部的引用,那么这个对象将不能被JVM正常回收,造成内存泄漏。 7、变量不合理的作用域     一个变量的定义的作用范围大于其使用范围,很有可能会造成内存泄漏。如果没有及时地把对象设置为null,可能导致内存泄漏。 5、改变哈希值       当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。
点赞 回复
分享
发布于 2020-04-28 12:22
内存泄漏简单地说就是不再会被使用的对象的内存不能被回收。 对象都是有生命周期的,有的长,比如老年代的对象,有的短,比如新生代的对象。如果长生命周期的对象持有短生命周期的引用,就很可能会出现内存泄露。 1.静态的容器,如HashMap、ArrayList,静态容器中保有着其他无用对象的引用,会导致无用对象无法被回收,而静态的容器的生命周期是与进程生命周期一致的。 比如 HashMap.put(Key, Object);而这个Object值却是null的话,会造成Object无法被回收。 2.各种提供close()方法的对象 比如Hibernate。我们操作数据库时,通过SessionFactory获取一个session。 Session session=sessionFactory.openSession();  完成后我们必须调用close()方法关闭:session.close(); SessionFactory就是一个长生命周期的对象,而session相对是个短生命周期的对象,但是框架这么设计是合理的:它并不清楚我们要使用session到多久,于是只能提供一个方法让我们自己决定何时不再使用。如果没有调用close()方法,资源连接是不会被GC垃圾回收器回收的。 3.单例模式导致内存泄漏 因为单例模式static的对象是存放在方法区中的。不会被回收。jdk1.8之后存到了元空间。并且,这个static对象具有JVM的整个生命周期,是一个长生命周期的对象,如果引用短生命周期的对象,很可能会导致内存泄漏 4.内部类和外部模块的引用  其实原理依然是一样的,只是出现的方式不一样而已。 5.容器如HashSet中修改了其中的值,因为HashSet内部是封装了HashMap的,所以当对HashSet中的元素进行修改时,会改变该元素的HashCode,也就是说会改变该元素在HashMap中的存放位置,但是由于没有改变在HashSet中的存放位置,因此使用remove()方法都无法进行移除,这就会造成内存泄漏 解决办法是重写hashcode()和equals()方法 而造成内存泄漏,我们可以对其进行排查。 1.使用虚拟机进程状况工具jps,确定频繁Full GC现象 2.使用jmap,找出导致频繁Full GC的原因 3.使用MAT查看,定位到代码,
点赞 回复
分享
发布于 2020-04-28 15:52
阅文集团
校招火热招聘中
官网直投

相关推荐

点赞 2 评论
分享
牛客网
牛客企业服务