关于Java内存泄漏

简介:    Java中由于有垃圾收集器(GC)自动回收资源,所以一般情况下不需要担心内存泄漏的问题。这也是Java相对C/C++而言开发简单高效的重要原因之一。想必调试过C/C++内存泄漏障害的人都深有体会。
   Java中由于有垃圾收集器(GC)自动回收资源,所以一般情况下不需要担心内存泄漏的问题。这也是Java相对C/C++而言开发简单高效的重要原因之一。想必调试过C/C++内存泄漏障害的人都深有体会。但是如果认为Java中不存在内存泄漏也是不对的。因为GC不是万能的,也有它失灵的时候。那它什么情况下会失灵呢?先简单了解一下GC的工作方式吧。

   垃圾收集器每过一段时间就会将不再使用的资源回收。GC判断一个对象是否是不再使用的方法非常重要。它以每个活的线程对象为根检查有没有能够到达目标对象的引用链为判断标准。如果不可达则说明该对象对程序(或者线程)的执行是不可见的,因为没有任何手段可以引用该对象,自然这个对象肯定是不再被使用了。于是将其回收。

   简单思考一下,上面的判断逻辑只是“什么是不使用对象”的充分条件,而不是必要条件。至于必要条件是什么,答案只有开发者自己知道,因为只有开发者自己才能准确知道哪些对象已经确实不再需要了,GC又怎么能揣测到开发者的意图呢?

   理解了这一点我们就知道了Java内存泄漏的第一种模式:GC不能正确识别出不再使用的对象。既:存在一条以活的线程对象(通常是主线程)为起点的引用链,指向了已经不再使用的对象。并且这些对象在程序运行中未能及时释放后者数目不断增长导致内存消耗过大(如果内存消耗能始终保持在可接受的范围之内,就谈不上什么内存泄漏了)。这样的内存泄漏通常发生在一个集合对象上,尤其是作为高速缓存使用的集合对象。

   本来我以为刚才提到的模式是Java内存泄漏唯一的一种模式,但是一次实际经历使我看到了第二种Java内存泄漏的模式:GC不能正常释放它想释放的对象。这是由于用户重载了某个Java对象的finalize()方法,GC在释放这个对象时就要调用这个被修改了的finalize()方法,而这个finalize()方法又由于某个原因离奇地无法结束(比如等待某个同步对象或者发生了死循环*),也就导致这个对象没法被正常释放,于是内存泄漏自然就发生了。当然这种情况比起前面提到的第一种模式要少见的多。

* 我遇到的情况是finalize()方法在等待一个同步对象,但是该同步对象又被别的线程长时间霸占着。这个线程虽然也有释放同步对象,但这个线程循环执行并且垃圾收集的线程优先级比较低,所以释放了的同步对象很快又被它抢了去。并且这个线程在执行过程中又会创建新的修改了finalize()方法的Java对象,导致该Java对象虽然也能被释放,但释放的速度跟不上创建的数据,时间久了,内存消耗就会越来越大,内存泄漏也就发生了。
相关文章
|
14天前
|
存储 Java 编译器
Java内存区域详解
Java内存区域详解
29 0
Java内存区域详解
|
24天前
|
缓存 算法 Java
Java内存管理与调优:释放应用潜能的关键
【4月更文挑战第2天】Java内存管理关乎性能与稳定性。理解JVM内存结构,如堆和栈,是优化基础。内存泄漏是常见问题,需谨慎管理对象生命周期,并使用工具如VisualVM检测。有效字符串处理、选择合适数据结构和算法能提升效率。垃圾回收自动回收内存,但策略调整影响性能,如选择不同类型的垃圾回收器。其他优化包括调整堆大小、使用对象池和缓存。掌握这些技巧,开发者能优化应用,提升系统性能。
|
1月前
|
监控 Java 数据库连接
解析与预防:Java中的内存泄漏问题
解析与预防:Java中的内存泄漏问题
|
20天前
|
缓存 安全 Java
Java并发编程进阶:深入理解Java内存模型
【4月更文挑战第6天】Java内存模型(JMM)是多线程编程的关键,定义了线程间共享变量读写的规则,确保数据一致性和可见性。主要包括原子性、可见性和有序性三大特性。Happens-Before原则规定操作顺序,内存屏障和锁则保障这些原则的实施。理解JMM和相关机制对于编写线程安全、高性能的Java并发程序至关重要。
|
28天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
79 0
|
2天前
|
Java 程序员 数据库连接
Java从入门到精通:3.3.2性能优化与调优——内存管理篇
Java从入门到精通:3.3.2性能优化与调优——内存管理篇
Java从入门到精通:3.3.2性能优化与调优——内存管理篇
|
3天前
|
存储 安全 Java
滚雪球学Java(19):JavaSE中的内存管理:你所不知道的秘密
【4月更文挑战第8天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
30 4
滚雪球学Java(19):JavaSE中的内存管理:你所不知道的秘密
|
10天前
|
存储 缓存 监控
Java内存管理:垃圾回收与内存泄漏
【4月更文挑战第16天】本文探讨了Java的内存管理机制,重点在于垃圾回收和内存泄漏。垃圾回收通过标记-清除过程回收无用对象,Java提供了多种GC类型,如Serial、Parallel、CMS和G1。内存泄漏导致内存无法释放,常见原因包括静态集合、监听器、内部类、未关闭资源和缓存。内存泄漏影响性能,可能导致应用崩溃。避免内存泄漏的策略包括代码审查、使用分析工具、合理设计和及时释放资源。理解这些原理对开发高性能Java应用至关重要。
|
18天前
|
存储 缓存 安全
【企业级理解】高效并发之Java内存模型
【企业级理解】高效并发之Java内存模型
|
25天前
|
Java
java中jar启动设置内存大小java -jar 设置堆栈内存大小
java中jar启动设置内存大小java -jar 设置堆栈内存大小
12 1