每日牛客网-2022/1/3 错题解析

面试题目精选:

讲一下JVM的内存结构?(来源牛客网)

JVM分为5大区域:程序计数器,虚拟机栈,本地方法栈,堆,方法区

程序计数器:

线程私有的,作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址。程序计数器主要有两个作用。

1.当前线程所执行的字节码的行号指示器,通过他实现代码的流程控制。如顺序执行,选择,循环,异常处理。

2.在多线程的情况下,程序计数器用于记录当前线程执行的位置,当线程被切换回来的时候能够知道它上次执行的位置。

虚拟机栈:Java虚拟机栈是由一个个栈帧组成的,而且每个栈中都拥有:局部的变量表,操作数栈,动态链接,方法出口信息。每一次函数调用都会有一个对应的栈帧被压入虚拟机栈,每一个函数被调用结束之后,都会有一个栈帧被弹出。

每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,在方法调用过程中,会进行动态链接,将这个符号引用转化为直接引用。

  • 部分符号引用在类加载阶段的时候就转化为直接引用,这种转化就是静态链接
  • 部分符号引用在运行期间转化为直接引用,这种转化就是动态链接

Java 虚拟机栈也是线程私有的,每个线程都有各自的 Java 虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡。Java 虚拟机栈会出现两种错误:StackOverFlowError 和 OutOfMemoryError

可以通过-Xss参数来指定每个线程的虚拟机栈内存大小:java -Xss2M

本地方法栈

虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。Native 方法一般是用其它语言(C、C++等)编写的。

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

堆用于存放对象实例,是垃圾收集器管理的主要区域,因此也被称作GC堆。堆可以细分为:新生代(Eden空间、From SurvivorTo Survivor空间)和老年代。

通过 -Xms设定程序启动时占用内存大小,通过-Xmx设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。

1

java -Xms1M -Xmx2M

方法区

方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

对方法区进行垃圾回收的主要目标是对常量池的回收和对类的卸载

永久代:方法区是JVM的规范,而永久代perGen是方法区的一种实现方式,并且只有HotSpot有永久代。对于其他类型的虚拟机。如JRockit没有永久代。由于方法区主要存储类的相关信息,所以对于动态生成类的场景比较容易出现永久代的内存溢出。

元空间:

JDK1.8的时候,HostSpot的永久代被彻底移除了,使用元空间替代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现,两者的最大区别在于:元空间并不在虚拟机中,而是直接内存。

说一下堆栈的区别?

1.堆的物理地址分配是不连续的,性能较慢;栈的物理地址分配是连续的,性能也是相对于比较快的。

2.堆存放的是对象的实例和数组;栈存放的是局部变量,操作数栈,返回结果等。

3.堆是线程共享的,栈是线程私有的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值