JVM面试题--JVM组成

JVM是什么

Java Virtual Machine Java程序的运行环境(java二进制字节码的运行环境)

运行流程

什么是程序计数器?

程序计数器:线程私有的,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。

我们知道java代码想要运行,需要先把java的源码编译为class字节码文件,在字节码文件当中详细说明了代码的执行过程

Java堆

线程共享的区域:主要用来保存对象实例,数组等,当堆中没有内存空间可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常。

在jdk8之后,方法区/永久代被放到了本地内存中,也叫做元空间

为什么方法区要放到本地内存呢

因为元空间或者说方法区主要存储的就是一些类或者常量,项目随着动态类加载的情况越来越多,这块内存变得越来越不可控。内存小了,会容易出现内存溢出;大了的话又会浪费内存。所以将方法区要放到本地内存可以防止堆空间内存溢出

总结

什么是虚拟机栈

垃圾回收是否涉及栈内存?

垃圾回收主要指就是堆内存,当栈帧弹栈以后,内存就会释放

栈内存分配越大越好吗?

未必,默认的栈内存通常为1024k

栈帧过大会导致线程数变少,例如,机器总内存为512m,目前能活动的线程数则为512个,如果把栈内存改为2048k,那么能活动的栈帧就会减半

方法内的局部变量是否线程安全?

如果方法内局部变量没有逃离方法的作用范围,它是线程安全的

如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全

什么时候会出现栈内存溢出?

总结

堆栈的区别是什么?

栈内存一般会用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的的。堆会GC垃圾回收,而栈不会。

栈内存是线程私有的,而堆内存是线程共有的。

两者异常错误不同,但如果栈内存或者堆内存不足都会抛出异常。

栈空间不足:java.lang.StackOverFlowError。

堆空间不足:java.lang.OutOfMemoryError。

能不能解释一下方法区?

方法区(Method Area)是各个线程共享的内存区域(这点和堆一样)

主要存储类的信息、运行时常量池

虚拟机启动的时候创建,关闭虚拟机时释放

如果方法区域中的内存无法满足分配请求,则会抛出OutOfMemoryError: Metaspace

常量池

运行时常量池

总结

直接内存

直接内存(操作系统内存):并不属于JVM中的内存结构,不由JVM进行管理。是虚拟机的系统内存,常见于 NIO 操作时,用于数据缓冲区,它分配回收成本较高,但读写性能高

我们平常的io操作就是bio

常规IO的数据拷贝流程

首先我们知道java并不具备磁盘读写的能力,他必须调用操作系统提供的函数,这里就会调用本地方法(native修饰)来操作磁盘文件

当用户态转变为内核态,这时候就会由cpu的函数区读取磁盘中的文件读取进来,然后会在操作系统中划出一块缓冲区,叫做系统缓冲区。利用缓冲区进行分批次的读取,但是这块缓冲区java代码是没法运行的,这是会在堆中划分一块java缓冲区。

这时候就进行到了下一个阶段,调用输出流的写入操作,进行反复读写,就可以复制到一个目标的位置。但是因为有两块缓冲区,可能会造成不必要的数据的复制,因此效率不高

NIO数据拷贝流程

与上面不同,多了一块直接内存,无论是操作系统还是java代码都可以进行访问

总结

相关推荐
吾爱星辰7 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
介亭7 小时前
internal.KaptWithoutKotlincTask$KaptExecutionWorkAction 问题 ---Room数据库
jvm
小飞猪Jay8 小时前
C++面试速通宝典——13
jvm·c++·面试
Ray Wang21 小时前
3.JVM
jvm
java6666688882 天前
Java中的对象生命周期管理:从Spring Bean到JVM对象的深度解析
java·jvm·spring
生产队队长2 天前
JVM(HotSpot):字符串常量池(StringTable)
jvm
Yuan_o_2 天前
JVM(Java Virtual Machine) 详解
jvm
派大星-?2 天前
JVM内存回收机制
jvm
G丶AEOM2 天前
Hotspot是什么?
jvm·hotspot
太阳伞下的阿呆3 天前
Java内存布局
jvm·内存对齐·内存布局·压缩指针