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代码都可以进行访问

总结

相关推荐
今天的砖头有点烫手啊1 天前
Java 对象内存布局:压缩指针、对齐填充与 JOL 实测
java·jvm
凯凯姜1 天前
JVM 内存持续增长与 Full GC 频繁
jvm
驭渊的小故事1 天前
从 JVM 底层看泛型:泛型擦除、Signature 属性与 Super Type Token 模式
java·开发语言·jvm
香蕉大香蕉(06敬畏市场)2 天前
高频八股 · Java 并发编程(10):异步、ThreadLocal 与虚拟线程(收官)
java·开发语言·网络·jvm·python·ai·实习
wuminyu2 天前
JVM规范学习总结-Class文件结构
java·linux·c语言·jvm·c++
酌沧3 天前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
wuminyu3 天前
JVM规范学习总结-Java源码经过javac编译后产物
java·linux·c语言·jvm·c++
学到老活到老4 天前
类已经加载了,为什么静态代码还没执行?
java·jvm
学到老活到老4 天前
写了 new,就一定会在堆上分配对象吗?
java·jvm
笨笨饿4 天前
# 59_CSDN博客自动写流程文章
linux·jvm·stm32·单片机·嵌入式硬件·mcu·51单片机