当前位置: 首页 > backend >正文

【Java虚拟机】JVM相关面试题

内存泄漏和内存溢出的理解

内存泄漏是指程序在运行过程中,一些不再被使用的对象仍然被引用,导致无法被垃圾回收,可用的内存逐渐减少。虽然Java程序中有垃圾回收机制,但是仍然有部分对象被不再使用的引用持有。

内存泄漏的原因可能有一下几种:

  • 被静态集合(HasMap,ArrayList等)使用后未销毁
  • 未停止的线程还有对该对象的引用
  • 未取消对事件源的监听,导致持续被引用

内存溢出是指JVM在申请内存时,无法找到足够的内存的情况。常发生在堆中不足以存放新创建的对象时。

内存溢出常见的原因有:

  • 被静态数据结构长时间持有
  • 大量对象创建
  • 方法不断递归调用导致栈溢出

JVM中有哪几种内存溢出的情况

  • 堆内存溢出:可能是由于大量对象的创建导致堆内存不足,从而导致溢出
  • 栈溢出:方法循环调用,没有出口,不断地压栈,导致栈溢出
  • 元空间溢出:可能是由于系统代码太多,或者引入的第三方包或者类库太多,导致溢出
  • 直接内存溢出

创建对象的过程

  • 类加载检查:首先根据new关键字的参数,去常量池中寻找该参数所对应的类,并检查是否被解析,加载,初始化过,如果没有,先去执行类加载过程
  • 分配空间:当类加载检查完毕后我们就可以知道该对象的内存,我们就可以在堆中为其划分一块内存
  • 初始化0值:将分配到的内存空间全部初始化为0值,这样可以在该对象没有被初始化时就可以访问该字段
  • 进行必要的设置,比如对象头等
  • 执行init方法:从Java虚拟机角度来看,已将完成了对象的创建,但是从Java代码的层面来看,对象的创建才刚刚开始,也就是执行到构造方法这一步了

对象的生命周期

  • 创建:通过new关键字在堆中为其分配一块内存,完成对象的创建
  • 使用:在Java代码中调用该对象的字段或方法。
  • 销毁:当垃圾回收器检测到该对象不再被引用时,会触发垃圾回收机制,释放该对象所占用的内存

类加载器有哪些

  • 启动类加载器:它是由c++编写的,是类加载器的最顶层,负责加载Java的核心类库。它在Java程序中不能被直接引用
  • 扩展类加载器:它是由Java语言实现的,它负责加载Java扩展目录下的jar包和类库,它的父类是启动类加载器并且它是由启动类加载器加载的
  • 应用程序类加载器:它也是由Java语言实现的,它负责加载用户类路径下的类库。它是我们编写Java程序默认的类加载器。它的父类是扩展类加载器。
  • 用户自定义类加载器:用户可以根据自身需求去自定义完成类加载器,这体现了Java程序的灵活性和扩展性。

什么是双亲委派原则

双亲委派原则是指当一个类加载器接收到类加载请求时,会将该请求委派给其父类,每一层都是这样,只有当父类表示自己不能加载该类时,子类才会尝试去加载。

双亲委派原则的作用

  • 保证类的唯一性:由于双亲委派原则会将类加载请求委派给父类,因此最终都会传递给启动类加载器,这样避免了不同类加载器加载相同类的情况。同时也避免了用户自定义类覆盖Java核心类库
  • 安全性:启动类加载器只会加载信任路径下的类库,因此这样可以防止假冒核心类库。
  • 支持隔离和层次划分:双亲委派原则支持不同层次的类加载器服务不同类加载请求。比如程序类加载器加载用户代码,扩展类加载器加载扩展程序,启动类加载器加载核心类库。这样层次更加分明有助于实现沙箱安全。
  • 简化加载流程:通过委派将类加载请求交给正确的类加载器加载,减少了每个类加载器加载的数量,简化了加载流程。

类加载过程

  • 加载:通过类的全限定名,获取该类的二进制字节流文件,并将该二进制字节流文件所代表的静态数据结构转化为方法区运行时的数据结构。
  • 连接:连接又分为三个阶段
  • 验证:验证二进制字节码是否符合虚拟机的需求,并且保证虚拟机不被损坏,和二进制字节码所对应信息的正确性。
  • 准备:为类的静态字段分配内存并初始化默认值
  • 解析:虚拟机将常量池中的字符流转化为字节流。
  • 初始化:这是类加载的最后一个阶段,简单来说就是执行类的构造器方法。但是这个构造器方法不是用户定义的,而是由虚拟机自动生成的
http://www.xdnf.cn/news/17754.html

相关文章:

  • RabbitMQ高级特性——消息确认、持久性、发送方确认、重试
  • tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
  • 反射在Spring IOC容器中的应用——动态创建Bean (补充)
  • Elasticsearch RBAC 配置:打造多租户环境的安全访问控制
  • CMake语法与Bash语法的区别
  • CV 医学影像分类、分割、目标检测,之【3D肝脏分割】项目拆解
  • 图论Day2学习心得
  • YouBallin正式上线:用Web3重塑创作者经济
  • 强化学习进化之路(GRPO->DAPO->Dr.GRPO->CISPO->GSPO)
  • 自由学习记录(84)
  • 回归算法:驱动酒店智能化定价与自动化运营的引擎—仙盟创梦IDE
  • STL容器详解:Vector高效使用指南
  • 机器学习(一)
  • [论文阅读] 人工智能 + 软件工程 | 从模糊到精准:模块化LLM agents(REQINONE)如何重塑SRS生成
  • 给电脑升级内存,自检太慢,以为出错
  • HTTPS 工作原理
  • 「iOS」————设计架构
  • Vue3 图片懒加载指令
  • 第4节 神经网络从公式简化到卷积神经网络(CNN)的进化之路
  • AI增强SEO关键词表现
  • 预训练模型在机器翻译中的应用:迁移学习的优势详解
  • 举例说明环境变量及 PATH 的作用
  • RuoYi-Vue3-FastAPI框架的功能实现(中)
  • 计算机网络技术学习-day1《网络乾坤:从比特洪流到协议星河的奇幻之旅》​
  • Dynamsoft Capture Vision Crack
  • 反射的详解
  • Vue3 vs Vue2:全面对比与面试宝典
  • BM25:概率检索框架下的经典相关性评分算法
  • 单例模式的理解
  • Windows11 运行IsaacSim GPU Vulkan崩溃