Java内存区域常见面试题01

java内存区域常见面试题及讲解

  1. java与c++之间存在一堵由内存分配垃圾回收的高墙,墙外的人想进去,墙里面的人想出来,你是怎么理解的?
    背景:这句话包含JVM领域的两个重点:内存分配与垃圾回收,虽然只有短短八字,能够把这八字背后隐含的原理解释明白却不容易,本篇以及后续文章也会陆陆续续对这八字庖丁解牛式讲解.废话不多说,直接上本题标准答案.
    答: c++程序员需要手动进行内存分配与垃圾回收,比较繁琐,对程序员要求较高,稍有不慎就会出现内存泄露和内存溢出.(解释了为什么c++为什么想跳墙)JVM实现了内存的自动管理,有虚拟机自动进行内存分配与垃圾回收,解放了程序员的双手.但由于什么都交给JVM完成,一旦出现内存泄露和内存溢出的问题,如果不了解虚拟机内存分配原理,排查起来将异常艰难.

  2. 请介绍一下JVM运行时数据区.
    :

    1. JVM在执行java程序的过程中会把它所管理的内存划分为若干不同数据区域,这些运行时区域统称为运行时数据.
      包括程序计数器、虚拟机栈、本地方法栈、堆区、方法区。
    2. 程序计数器
      程序计数器是一块较小的内存空间,可以看做当前线程(线程私有)所执行字节码的行号指示器。字节码解释器通过程序计数器来选取下一条需要执行的字节码指令。在多线程环境中,为了线程切换后能够恢复到正确的执行位置,所以程序计数器是线程私有的。如果执行的是本地方法
      (可以由其它语言编写),则该值为空。由于该区域值存储一个地址,不涉及到未知大小的数据块的存取,所以是==《java》虚拟机规范中唯一一个没有outofMemory情况的区域==
      3. java虚拟机栈
      java虚拟机栈也是线程私有的,是运行时的单位,与方法的运行密切相关。每个方法执行,JVM就会为该方法创建一个栈帧。一个方法对应一个栈帧。但由于该方法内可能调用了其它方法,所以虚拟机栈中某一时刻可能有多个栈帧。栈帧包含:局部变量表、操作数栈、动态连接、方法出口等信息
      。方法调用时,栈帧入栈,方法执行完毕,栈帧出栈。虚拟机栈的详细介绍请看Q4。
      未完待续。。。
  3. 线程 进程 运行时数据区域 对应关系

    1. 一个线程对应一个栈,生命周期一致
    2. 一个方法对应一个栈帧
  4. 请具体说明一下虚拟机栈的内部结构。

    1. 局部变量表
      局部变量表本质上是一个数字数组,用来存储该栈帧所对应方法的参数以及定义在该方法中的(局部)变量。包括基本数据类型和引用类型。基本数据类型(boolean,byte,char,short,int,long,float,double)、引用数据类型和returnAddress类型(指向了一条字节码指令的地址,jvm曾用它来处理异常,现在用异常表)。基本数据类型存其本身,引用数据类型存对象引用(关于对象引用详见10)。这两种类型本质上都是数字。
      局部变量表的基本存储单位是局部变量槽,64bit的long和double占两个槽,其余占一个。如果执行的是实例方法(没有static修饰),局部变量表第一个槽(索引为0)存储this对象(每个实例方法的隐含参数)的引用,其余索引依次分配给方法参数和局部变量.局部变量表的槽可以复用,即当pc所指示的字节码已经超出了局部变量的作用范围,该局部变量的槽可被复用,以节省内存空间.与类变量有准备阶段不同,局部变量只有一次赋值过程,所以局部变量定义的时候要赋初值
      2. 操作数栈
      操作数栈中可以"存储"任意类型的java数据结构.64位所占容量为2.操作数栈最大深度在编译时被写到code属性max_stack中.方法运行的本质是字节码指令操纵操作数栈里的操作数,操作数栈中可以"存储"任意类型的java数据结构.64位所占容量为2.操作数栈最大深度在编译时被写到==code属性max_stack中.方法运行的本质是字节码指令操纵操作数栈里的操作数,数据在操作数栈与局部变量表之间传递,最终完成方法的执行.

在这里插入图片描述

字节中的方法调用指令以常量池指向方法的符号引用为参数,常量池中的符号引用在类加载阶段或第一次运行(应该是main方法的类)期间被转化为直接引用,另一部分在每一次运行期间被转化为直接引用,称为动态连接.
4. 方法返回地址
方法返回有两种情况,一种是直接返回,一种是异常返回(没有一场处理逻辑,即字节码内没有一场处理相关字节码,class文件内自然没有异常表).无论哪种返回方式,都需要在栈帧中保存一部分信息.正常退出,一般保存主调方法的PC计数器的值,异常返回,交给异常处理器来决定.

  1. 为什么JVM指令根据栈来设计,而不是寄存器。
    JVM是跨平台的,而不同的CPU架构不同,所以不能基于寄存器。基于栈设计指令系统,指令集(包含的指令)变小,但是实现同样的功能需要更多的指令。
  2. JVM的跨平台性与跨语言性如何理解?
  3. 计算机组成原理,寄存器指令那一块
  4. 如何理解栈是运行时单位,堆是存储的单位?
    栈是解决程序运行问题的,即程序如何执行,如何处理数据。堆是解决数据存储问题,即出具存储在哪,如何存储。
  5. 为什么虚拟机栈不需要垃圾回收,运行时数据区还有哪些区域不需要GC?虚拟机栈有哪些常见的异常。
    因为虚拟机栈只有进栈出栈两种操作。调用方法,栈帧进栈,调用完成,栈帧出栈。程序计数器也不需要垃圾回收。
    异常:
    1.StackOverflowError
    栈深度确定,线程请求的栈帧深度大于虚拟机所允许的深度,通俗来说就是要存放的栈帧太多,栈盛不下了
    2. OutOfMemoryError
    栈上的深度可以动态拓展,当栈拓展时无法申请到足够的内存。通俗来说找不到足够的地方放栈帧。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弈师亦友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值