2024年处理Java程序中的内存泄漏,源码解析之Seata项目中的分布式ID生成算法

最后

一次偶然,从朋友那里得到一份“java高分面试指南”,里面涵盖了25个分类的面试题以及详细的解析:JavaOOP、Java集合/泛型、Java中的IO与NIO、Java反射、Java序列化、Java注解、多线程&并发、JVM、Mysql、Redis、Memcached、MongoDB、Spring、Spring Boot、Spring Cloud、RabbitMQ、Dubbo 、MyBatis 、ZooKeeper 、数据结构、算法、Elasticsearch 、Kafka 、微服务、Linux。

这不,马上就要到招聘季了,很多朋友又开始准备“金三银四”的春招啦,那我想这份“java高分面试指南”应该起到不小的作用,所以今天想给大家分享一下。

image

请注意:关于这份“java高分面试指南”,每一个方向专题(25个)的题目这里几乎都会列举,在不看答案的情况下,大家可以自行测试一下水平 且由于篇幅原因,这边无法展示所有完整的答案解析

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

在我们深入讨论之前,让我们先回顾一下垃圾收集是如何工作的。垃圾收集器的工作是找到应用程序不再需要的对象,并在它们不能被访问或引用时将其删除。垃圾收集器从根节点开始,根节点是在Java应用程序的整个生命周期中持续存在的类,它会遍历所有被引用的节点。在遍历节点时,它会跟踪哪些对象正在被引用。任何不再被引用的类都有资格被垃圾收集。当对象被删除时,这些对象使用的内存资源可以返回给Java虚拟机。

因此,Java代码确实不需要程序员来负责内存管理清理,并且它会自动垃圾收集未使用的对象。然而,要记住的关键一点是一个对象只有在不再被引用时才被认为是未使用的。图1说明了这个概念。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在上图中在执行一个Java应用程序期间具有不同生存期的两个类。Class A首先被实例化,并且在程序的整个生命周期中存在很长时间。在某个时刻,Class B被创建,Class A添加对此新创建的类的引用。现在让我们假设Class B是一些用户界面小部件,被用户显示并最终消除。尽管Class B不再需要,也应该被回收了,如果引用Class B的Class A没有被清除,Class B即使在下一个垃圾收集周期执行之后,也将继续存在并占用内存空间,那么这个时候Class B的对象实例就发生了内存泄露。

什么时候内存泄漏是一个问题?

如果程序执行一段时间后抛出一个`java.lang.OutOfMemoryError,内存泄漏肯定是一个很大的疑点。那么什么时候内存泄漏应该成为一个问题?完美主义程序员会回答这个问题全部需要调查和纠正内存泄漏。然而,在得出这个结论之前,还有几个其他的问题需要考虑,包括程序的生命周期和泄漏的大小。

考虑垃圾收集器在应用程序生命周期中可能永远不会运行的可能性。无法保证JVM何时或是否会调用垃圾收集器——即使程序显式调用System.gc()。通常,垃圾收集器不会自动运行,直到程序需要比当前可用内存更多的内存。此时,JVM将首先尝试通过调用垃圾收集器来获得更多的可用内存。如果这种尝试仍然没有释放足够的资源,那么JVM将从操作系统获得更多的内存,直到它最终达到允许的最大值。

以一个小型的Java应用程序为例,它显示一些简单的用户界面元素用于配置修改,并且存在内存泄漏。很有可能在应用程序关闭之前,垃圾收集器甚至不会被调用,因为JVM可能有足够的内存来创建程序所需的所有对象,并有剩余的内存来备用。因此,在这种情况下,即使一些死对象在程序执行时占用了内存,但对于所有实际用途来说,这真的无关紧要。

如果正在开发的Java代码打算一天24小时在服务器上运行,那么内存泄漏比我们的配置实用程序的情况要严重得多。即使是某些代码中本来应该连续运行的最小漏洞,最终也会导致JVM耗尽所有可用的内存。

最后一个考虑是,Java内存泄漏不应该被视为像其他语言(如C++)中发生的那样危险,因为在其他语言中,内存会丢失,永远不会返回到操作系统。在Java应用程序的情况下,对象都是依附在操作系统给JVM的内存资源上。因此,理论上,一旦Java应用程序及其JVM关闭,所有分配的内存都将返回给操作系统。

常见内存泄露情况

长生命周期的对象持有短生命周期对象的引用

例如将ArrayList设置为静态变量,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏

连接未关闭

如数据库连接、网络连接和IO连接等,只有连接被关闭后,垃圾收集器才会回收对应的对象。

内部类持有外部类

Java的非静态内部类的这种创建方式,会隐式地持有外部类的引用,而且默认情况下这个引用是强引用,因此,如果内部类的生命周期长于外部类的生命周期,程序很容易就产生内存泄漏

如果内部类的生命周期长于外部类的生命周期,程序很容易就产生内存泄漏(你认为垃圾收集器会回收掉外部类的实例,但由于内部类持有外部类的引用,导致垃圾收集器不能正常工作)

学习分享,共勉

这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!

资料整理不易,读者朋友可以转发分享下!

Java核心知识体系笔记.pdf

记一次蚂蚁金服Java研发岗的面试经历,分享下我的复习笔记面经

中高级Java开发面试高频考点题笔记300道.pdf

记一次蚂蚁金服Java研发岗的面试经历,分享下我的复习笔记面经

架构进阶面试专题及架构学习笔记脑图

记一次蚂蚁金服Java研发岗的面试经历,分享下我的复习笔记面经

Java架构进阶学习视频分享

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

  • 13
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值