JVM面试题-JVM内存结构解析(图文详解)

2023-09-19 08:43:08

JVM内存结构

共享 和 隔离

线程共享区域:方法区、堆、直接内存

线程隔离区域:虚拟机栈、本地方法栈、程序计数器

线程共享:定义一个变量或者一个方法,多线程都可以同时访问、修改这个方法或者变量

线程隔离:就是数据不能被多个线程同时访问,某些数据只属于一个线程

1.程序计数器

线程私有的。

作用:记录线程执行到哪一步,保存的是字节码的行号,用于正在执行的字节码指令的地址

我的理解:相当于是一个线程的进度条,记录一下当前执行到的位置,这样CPU切换了别的线程之后,当前线程就不会丢失任务的进度,下次的话就可以继续执行。

什么时候入栈,什么时候出栈、什么时候进入循环、跳转、异常,线程恢复等等由程序计数器来进行记录。

2.虚拟机栈

java中的栈通常是指虚拟机栈。

  • 虚拟机栈:每个线程运行时所需要的内存

  • 每个栈是由多个栈帧组成,对应这每次方法调用是所占的内存

  • 每个线程只能有一个活动栈帧,对应着正在执行的那个方法

虚拟机栈:线程私有的,每个方法执行的时候都会创建一一个栈帧, 用于存储局部(本地)变量表,里面存储的就是内存地址、操作数、动态链接和方法返回等信息,当线程请求的栈深度超过了虚拟机允许的最大深度时,就会抛出StackOverFlowError;

栈内存分配越大越好吗?

不是,因为增加栈大小,会造成每个线程的栈都变的很大,使得一定的栈空间下,能创建的线程数量会变小。

垃圾回收是否会涉及倒虚拟机栈?

不会;垃圾回收只会涉及到方法区和堆中,方法区和堆也会存在栈溢出的可能; 程序计数器,只记录运行下一行的地址,不存在栈溢出和垃圾回收; 虚拟机栈和本地方法栈,都是只涉及压栈和出栈,可能存在栈溢出,不存在垃圾回收.

栈内存溢出情况
  1. 栈帧过多导致栈内存溢出,典型问题:递归调用

  2. 栈帧过大导致栈内存溢出,你不改默认值的话一般不会出现这个问题

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

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

3.本地方法栈

操作系统的本地方法,跟java中的c语言是自己封装的,操作系统不认识,的需要操作系统的本地c语言进行翻译识别,最终一步翻译。

本地方法栈:线程私有的,保存的是本地方法的信息,当一个jvm创建的线程调用本地方法后,jvm不会在虚拟机栈中为该线程创建栈帧,而是简单的动态链接并直接调用调用操作系统提供的某些方法;

就是java的执行,最终需要把我们的方法翻译成操作系统可识别的语言,本地方法栈就是存放翻译后的方法

4.堆

是线程共享的,作用:存 对象实例、数组等。内存不够的时候:抛异常OutOfMemoryError

组成:又分为 年轻代 和 老年代

年轻代:被划分为三部分,Eden区和两个大小严格相同的Survivor区,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到老年代区间。 ​ 老年代:主要保存生命周期长的对象,一般是一些老的对象

java7和java8的 堆 区别:

Java8为了让堆节省空间,防止内存溢出,做了优化:把 方法区/永久代 放到了本地内存中。

  • 1.7中有有一个永久代,存储的是类信息、静态变量、常量、编译后的代码

  • 1.8移除了永久代,把数据存储到了本地内存的元空间中,防止内存溢出

5.方法区

线程共享的。

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

方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据,即永久代

类加载:JDK编译java文件后的class文件从磁盘加载到内存中,类一开始从磁盘加载到内存的时候先加载到方法区

Class文件中除了有类的版本、字段、方法、接口等描述信息

jdk1.8中不存在方法区了,被元数据区(元空间)替代了,原方法区被分成两部分:

1: 加载的类信息,2:运行时常量池;

加载的类信息被保存在元数据区中,运行时常量池保存在堆中;

字符串常量池

1、在JDK1.7前,运行时常量池+字符串常量池是存放在方法区中,HotSpot VM对方法区的实现称为永久代。

2、在JDK1.7中,字符串常量池从方法区移到堆中,运行时常量池保留在方法区中。

3、在JDK1.8中,HotSpot移除永久代,使用元空间代替,此时字符串常量池保留在堆中,运行时常量池保留在方法区中,只是实现不一样了,JVM内存变成了直接内存。

运行时常量区

运行时常量池是方法区的一部分

方法区是一个大数组,常量区是数组的一部分,类加载后的常量池表的内容存放到方法区的运行时常量池中

6.直接内存

不属于JVM的内存结构,是操作系统的内存,常见于NIO操作,主要用于数据缓冲区,它分配回收成本较高,但读写性能高

NIO比常规的IO 快很多,

因为常规IO读取文件的流程是: 磁盘文件 -》 系统缓存区 -》 java缓冲区。

NIO的话是:磁盘文件 -》 直接内存。直接内存是java堆内存和系统内存都能访问的,java代码访问的时候就比上面的方式烧了一次复制的步骤,所以速度快

更多推荐

Vue的详细教程--用Vue-cli搭建SPA项目

Vue的详细教程--用Vue-cli搭建SPA项目1.Vue-cli是什么2.什么是SPA项目1.vueinitwebpackspa2.一问一答模式2:运行完上面的命令后,我们需要将当前路径改变到SPA这个文件夹内,然后安装需要的模块此步骤可理解成:maven的web项目创建成功后,修改pom文件添加依赖3.启动并访问

MYSQL--索引

目录一、索引的概念:二、索引的作用:三、索引的缺点:四、创建索引的原则依据:五、索引的分类和创建:1.普通索引:2.唯一索引:3.主键索引:4.组合索引:5.全文索引:六、查看删除索引:1.查看索引:2.删除索引:一、索引的概念:索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于

SpringSecurity 初始化解析

文章目录前言加载SpringSecurity配置解析配置SpringSecurity解析器security:http解析FilterChainProxy的注册过程创建SpringSecurity过滤器总结前言通过上文分析知道了SpringSecurity对一个请求的具体处理流程。不知道大家是否跟我一样都有几个疑问:Fi

已知我有一个表格里有编号状态和名称的列,如何转换为目标样式?

点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤此臣所以报先帝而忠陛下之职分也。大家好,我是皮皮。一、前言前几天在Python最强王者交流群【黑科技·鼓包】问了一个Python自动化办公的问题,一起来看看吧。请教一下PANDA库的问题:已知我有一个表格里

字符串(字符数组)的各种操作功能

利用C语言编程平台以及所学的编程知识,完成以下工作:采用菜单形成,通过菜单项(1;2;3;......)等选择方式,分别实现以下对字符串(字符数组)的各种操作功能:初始化字符串(字符数组)A[],B[],C[]等,并键盘录入,要求字符串(字符数组)以’\0’为结束标志;调用自己编写的函数intlength(CharA[

JS基础语法

JS是一门面向对象的编程语言,运行在客户端的脚本语言,可以基于Node.js进行服务器端编程JS的作用:表单动态校验网页特效服务端开发浏览器执行JS:浏览器分为两部分:渲染引擎和JS引擎渲染引擎用来解析HTML和CSS,如chrome浏览器的Blink/Webkit,Firefox的Gecko。JS引擎用来读取网页的J

每日一练 | 华为认证真题练习Day1

Day1华为认证中级考试真题1、IP报文中用Tos字段进行QOS标记,Tos字段中是使用前6bit来标记DSCP的。A.正确​B.错误2、传统的丢包策略采用尾部丢弃(Tail-Drop)的方法,这种丢弃方法会导致TCP全局同步现场。A.正确B.错误3、下列选项中,属于AgileController的业务编排的亮点的是:

JavaScript函数this指向

一、this的指向规则1.this到底指向什么呢?我们先来看一个让人困惑的问题:定义一个函数,我们采用三种不同的方式对它进行调用,它产生了三种不同的结果//定义函数functionfoo(name){console.log("foo函数:",this)}//1.方式一:直接调用//foo()//2.方式二:通过对象调起

Revopoint的3D输出格式及转换工具

在CES展会期间,许多参观者向我们询问与我们的3D扫描仪相关的问题。最常见的问题包括我们的扫描仪导出的文件格式,以及该文件是否与3D打印机兼容?因此,我们决定回答这些问题,并在本文中对常见的3D文件格式进行一些简要介绍。计算机文件记录和存储数据,包括文本、图片、视频、计算机程序或其他类型的数据。就3D文件而言,顾名思义

代理IP在各种业务情境中的应用和优势

随着现代互联网的迅速发展,代理IP已成为一种广泛应用于各行业的网络技术。特别是在数据采集、网站建设、安全维护等领域,代理IP的应用越来越受到重视。那么,具体有哪些业务会使用到代理IP呢?我们一起来看一看。1.网络爬虫和数据采集网络爬虫和数据采集是代理IP的主要应用场景之一。大规模数据采集由于需要频繁对目标网站发送请求,

Docker快速入门到项目部署,docker自定义镜像

https://blog.csdn.net/m0_67184231/article/details/1331495792.3.自定义镜像前面我们一直在使用别人准备好的镜像,那如果我要部署一个Java项目,把它打包为一个镜像该怎么做呢?2.3.1.镜像结构要想自己构建镜像,必须先了解镜像的结构。之前我们说过,镜像之所以能

热文推荐