• JVM内存模型(面试题)


    简介

    Java虚拟机(JVM)内存模型定义了JVM在运行Java应用程序时如何管理内存的规则和机制。JVM内存模型主要分为以下几个部分:

    1. 方法区(Method Area): 方法区是JVM的一部分,用于存储类的元数据信息,例如类的结构、字段、方法代码等。在方法区中,还包含常量池,用于存储编译时生成的字面常量和符号引用。方法区通常在JVM启动时创建,它的大小可以通过命令行参数进行配置。

    2. 堆内存(Heap): 堆内存是用于存储Java对象实例的区域。所有通过new关键字创建的对象都存储在堆内存中。堆内存是JVM中最大的内存区域,也是垃圾回收的主要工作区域。堆内存的大小可以通过命令行参数进行配置,但它的大小通常是动态分配的,取决于应用程序的需求。

    3. 虚拟机栈(Java Virtual Machine Stacks): 虚拟机栈是每个线程独有的,用于存储方法的局部变量、方法参数、返回地址和操作数栈等信息。每个方法的调用都会在虚拟机栈上创建一个帧(Frame),帧中包含了方法的局部变量表和操作数栈。虚拟机栈有固定的深度,超出深度会抛出栈溢出异常。

    4. 本地方法栈(Native Method Stacks): 本地方法栈类似于虚拟机栈,但它是为本地(Native)方法服务的,本地方法是用其他语言(如C或C++)编写的方法,可以被Java调用。本地方法栈的大小也可以通过命令行参数进行配置。

    5. 程序计数器(Program Counter): 程序计数器是每个线程私有的,用于存储当前线程执行的字节码指令地址。在多线程环境下,程序计数器用于线程切换时恢复执行位置。

    6. 直接内存(Direct Memory): 直接内存并不是JVM内部的一部分,但它与JVM密切相关。直接内存是使用java.nio包中的ByteBuffer等类时分配的,它不受JVM内存管理的控制,而是由操作系统管理的。通常用于I/O操作和NIO(New I/O)库。

    7. 元空间(Metaspace): 元空间是方法区的替代,用于存储类的元数据信息。与方法区不同,元空间的大小可以根据应用程序的需求动态增长,不再有固定的上限。元空间的内存通常由操作系统管理,不再受到JVM的直接限制。

    需要注意的是,JVM内存模型的具体实现可以因不同的JVM厂商和版本而有所不同,因此在特定的JVM上可能会有一些细微的差异。理解JVM内存模型对于Java开发人员非常重要,因为它有助于优化内存使用、处理内存泄漏和性能调优等方面的任务。

    一、介绍下JVM的内存模式

    1、堆和方法区都是线程公有

    2、栈和计数器是线程私有

    二、堆里面都有哪些东西 

    1、分为新生代和老年代。

    2、新生代分为,伊甸园和S0,S1区

    三、垃圾回收算法都有哪些

    1、标记-清除算法

    缺点:极端情况下,需要标记大量的对象进行回收时,执行效率会跟着对象的数量增长而降低,以及存在不连续空间

    2、复制-清除算法

    优点,解决标记清除算法的,不连续空间的问题,

    缺点:如果存活对象比较多,复制的对象较多,效率也会降低

    3、标记-整理算法

    1、标记存活的对象,并进行整理,解决了标记-清除碎片空间的问题(老年代采用)

    2、其余使用标记-清除算法,暂时可以容忍碎片空间问题,直到容忍不了了,采用标记-整理

    3、整理的时候,会停止项目的运行

    四、垃圾回收器

    1、新生代:Serial,ParNew,ParallelScavenge 

    2、老年代:CMS,MSC,ParallelOld

    3、整体回收:G1 

    五、永久代和元空间的有什么不同

    永久代是JVM 7之前版本中的方法区实现,而元空间是JVM 8及以后版本的新方法区实现。元空间不再有固定大小,而永久代有限制。永久代容易导致内存泄漏和OutOfMemoryError,而元空间更加灵活。 

      六、方法区存储了什么

    方法区存储类的元数据信息,包括类的结构、字段、方法代码、常量池等

    七、什么是双亲委派

    双亲委派模型是一种类加载器的工作机制,它通过父类加载器尝试加载类,只有在父类加载器无法加载时,才由子类加载器加载,从而确保类的唯一性和安全性。 

    八、jvm内存管理如何工作 

    JVM负责管理Java应用程序的内存,包括堆内存、方法区、虚拟机栈等。它通过垃圾回收机制来自动回收不再被引用的对象,释放内存。

    九、JVM的运行时数据区域有哪些? 

    JVM的运行时数据区域包括堆、方法区、虚拟机栈、本地方法栈、程序计数器、元空间(或永久代,取决于JVM版本)

    十、什么是Java虚拟机栈溢出(StackOverflowError)和堆内存溢出(OutOfMemoryError)?如何避免它们? 

    1. Java虚拟机栈溢出通常是由于方法调用层次太深,导致栈空间耗尽。堆内存溢出通常是由于创建太多对象,导致堆空间耗尽。可以通过优化递归调用和合理管理内存来避免这些问题。

    这些问题涵盖了JVM的基本概念和一些高级主题,对于Java开发人员来说,了解JVM是非常重要的,因为它直接影响到应用程序的性能和稳定性。在面试中,这些问题可能会被用来评估候选人的Java基础知识和编程经验。

    十一、什么是Java堆和Java栈?它们之间有什么区别?

     Java堆是用于存储对象实例的内存区域,而Java栈是用于存储方法调用和局部变量的内存区域。主要区别在于,堆是共享的,存储对象的实例,而栈是线程私有的,存储方法调用的信息和局部变量。栈内存的生命周期短暂,而堆内存的生命周期更长。

    十二、什么是JVM?它的主要作用是什么?

    答: JVM是Java虚拟机的缩写,它是Java程序的运行环境,负责将Java源代码编译成字节码并执行。它的主要作用包括字节码解释、内存管理、垃圾回收、即时编译等。

  • 相关阅读:
    JavaScript中的变量
    led台灯哪个牌子质量好?2022最新的台灯牌子排名
    Vue中的.sync修饰符
    内存性能指标及工具
    SpringCloud微服务技术栈-什么是Docker?怎么安装Docker?
    Postman for Mac(HTTP请求发送调试工具)v10.18.10官方版
    Android Splash实现
    Shrio整合Jwt
    《天天数学》连载51:二月二十日
    C++中的各种函数及用法(2)
  • 原文地址:https://blog.csdn.net/yanghezheng/article/details/126727549