经典面试题|讲一讲JVM的组成

JVM(Java 虚拟机)算是面试必问的问题的了,而但凡问 JVM 一定会问的第一个问题就是:讲一讲 JVM 的组成?那本文就注重讲一下 JVM 的组成。

首先来说 JVM 的组成分为,整体组成部分和运行时数据区组成部分,一般开发者关注的和面试官问的都是后者,但本文会详细讲解以上两个组成部分。

一、JVM 整体组成

JVM 整体组成可分为以下四个部分:

  1. 类加载器(ClassLoader)
  2. 运行时数据区(Runtime Data Area)
  3. 执行引擎(Execution Engine)
  4. 本地库接口(Native Interface)

各个组成部分的用途:

程序在执行之前先要把java代码转换成字节码(class文件),jvm首先需要把字节码通过一定的方式 类加载器(ClassLoader) 把文件加载到内存中 运行时数据区(Runtime Data Area) ,而字节码文件是jvm的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 执行引擎(Execution Engine) 将字节码翻译成底层系统指令再交由CPU去执行,而这个过程中需要调用其他语言的接口 本地库接口(Native Interface)来实现整个程序的功能,这就是这4个主要组成部分的职责与功能。

而我们通常所说的jvm组成指的是运行时数据区(Runtime Data Area),因为通常需要程序员调试分析的区域就是“运行时数据区”,或者更具体的来说就是“运行时数据区”里面的Heap(堆)模块,那接下来我们来看运行时数据区(Runtime Data Area)是由哪些模块组成的。

二、运行时数据区组成

jvm的运行时数据区,不同虚拟机实现可能略微有所不同,但都会遵从Java虚拟机规范,Java 8 虚拟机规范规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域:

  1. 程序计数器(Program Counter Register)
  2. Java虚拟机栈(Java Virtual Machine Stacks)
  3. 本地方法栈(Native Method Stack)
  4. Java堆(Java Heap)
  5. 方法区(Methed Area)

接下来我们分别介绍每个区域的用途。

①、Java程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解析器的工作是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

特性:内存私有

由于jvm的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,也就是任何时刻,一个处理器(或者说一个内核)都只会执行一条线程中的指令。因此为了线程切换后能恢复到正确的执行位置,每个线程都有独立的程序计数器。

异常规定:无

如果线程正在执行Java中的方法,程序计数器记录的就是正在执行虚拟机字节码指令的地址,如果是Native方法,这个计数器就为空(undefined),因此该内存区域是唯一一个在Java虚拟机规范中没有规定OutOfMemoryError的区域。

②、Java虚拟机栈

Java虚拟机栈(Java Virtual Machine Stacks)描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个线帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每个方法从调用直至执行完成的过程,都对应着一个线帧在虚拟机栈中入栈到出栈的过程。

特性:内存私有,它的生命周期和线程相同。

异常规定:StackOverflowError、OutOfMemoryError

1、如果线程请求的栈深度大于虚拟机所允许的栈深度就会抛出StackOverflowError异常。

2、如果虚拟机是可以动态扩展的,如果扩展时无法申请到足够的内存就会抛出OutOfMemoryError异常。

③、本地方法栈

本地方法栈(Native Method Stack)与虚拟机栈的作用是一样的,只不过虚拟机栈是服务Java方法的,而本地方法栈是为虚拟机调用Native方法服务的。

在Java虚拟机规范中对于本地方法栈没有特殊的要求,虚拟机可以自由的实现它,因此在Sun HotSpot虚拟机直接把本地方法栈和虚拟机栈合二为一了。

特性和异常: 同虚拟机栈,请参考上面知识点。

④、Java堆

Java堆(Java Heap)是Java虚拟机中内存最大的一块,是被所有线程共享的,在虚拟机启动时候创建,Java堆唯一的目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,随着JIT编译器的发展和逃逸分析技术的逐渐成熟,栈上分配、标量替换优化的技术将会导致一些微妙的变化,所有的对象都分配在堆上渐渐变得不那么“绝对”了。

特性:内存共享

异常规定:OutOfMemoryError

如果在堆中没有内存完成实例分配,并且堆不可以再扩展时,将会抛出OutOfMemoryError。

Java虚拟机规范规定,Java堆可以处在物理上不连续的内存空间中,只要逻辑上连续即可,就像我们的磁盘空间一样。在实现上也可以是固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是可扩展的,通过-Xmx和-Xms控制。

⑤、方法区

方法区(Methed Area)用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

误区:方法区不等于永生代

很多人原因把方法区称作“永久代”(Permanent Generation),本质上两者并不等价,只是HotSpot虚拟机垃圾回收器团队把GC分代收集扩展到了方法区,或者说是用来永久代来实现方法区而已,这样能省去专门为方法区编写内存管理的代码,但是在Jdk8也移除了“永久代”,使用Native Memory来实现方法区。

特性:内存共享

异常规定:OutOfMemoryError

当方法无法满足内存分配需求时会抛出OutOfMemoryError异常。

三、扩展知识

本节将扩展一些和内存分配有关的知识。

运行时常量池

运行时常量池是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table)用于存放编译期生成的各种字面量和符号引用,这部分在类加载后进入方法区的运行是常量池中,如String类的intern()方法。

直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,但这部分内存也会被频繁的使用,而且可能导致OutOfMemoryError。在JDK 1.4中新加入了NIO类,引入了一种基于Channel与缓冲区Buffer的IO方式,它通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用操作,它因此更高效,它避免了Java堆和Native堆来回交换数据的时间。

注意 :直接内存分配不会受到Java堆大小的限制,但是受到本机总内存大小限制,在设置虚拟机参数的时候,不能忽略直接内存,把实际内存设置为-Xmx,使得内存区域的总和大于物理内存的限制,从而导致动态扩展时出现OutOfMemoryError异常。

四、总结

本文讲了jvm的主要组成部分,以及组成部分中最重要的运行时数据区(Runtime Data Area)的构成,其中程序计数器、虚拟机栈和本地方法为私有内存,会随着线程而生,随着线程而灭,而Java堆作为最大的内存区域将是开发人员重点关注的内存区域,还有方法区以及运行时常量区与永生代的关系,最后讲了直接内存的实现过程已经使用时需要主要的点,希望能够帮助大家更好的理解jvm。

五、参考资料

《深入理解Java虚拟机》


关注下方二维码,订阅更多精彩内容。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ST-GCN训练自建数据集

参考了许多博文,慢慢地也就把st-gcn跑出来了,参考的文章一会附在文章里面,实测有用。 1.安装st-gcn 复现STGCN CPU版 (ubuntu16.04pytorch0.4.0openposecaffe)_Significance的博客-程序员秘密​​​​​​复现旧版STG…

[翻译] Haneke(处理图片缓存问题)

Haneke https://github.com/hpique/Haneke A lightweight zero-config image cache for iOS. 轻量级0配置图片缓存。 Haneke resizes images and caches the result on memory and disk. Everything is done in background, allowing for fast, responsive scrolling. Asking H…

Linux Shell编程之别名和常用快捷键

1.给命令起得别名,就是小名 例:给vim命令起个别名vi alias vivim2.取消别名 unalias vi常用快捷键: ctrl C 强制终止当前命令 ctrl L 清屏 ctrl U 删除或剪切光标之前内容的命令 ctrl K 删除或剪切光标之后内容的命令 ctrl Y 粘贴ctr…

面试题:为什么Java中的字符串对象是不可变的

阅读本文大概需要 4分钟。所谓不可变对象,是指一个对象在创建后,它的内部状态不会被改变的对象。这意味着当我们将一个不可变对象的引用赋值给某个变量后,我们就不能改变该对象的内部状态。 James Gosling也说过——Java开发者应该尽量使用不…

复现STGCN CPU版 (ubuntu16.04+pytorch0.4.0+openpose+caffe)

前提:ubuntu下将python3.5.2设为默认(百度) 一.下载stgcn (gitbub上fork后导入到gitee快些): st-gcn: Spatial Temporal Graph Convolutional Networks (ST-GCN) for Skeleton-Based Action Recognition in PyTorch…

arm-hisiv100nptl-linux-gcc编译boa和移植

工作需要,移植web服务器到摄像头中,查找资料,借鉴了几位前辈的文章自己弄了一下,还挺顺利的呦~系统:centos 6.4 64bit工具:arm-hisiv100nptl-linux-gcc1、交叉编译1)从www.boa.org下载Boa源码&a…

Linux Shell编程之输入输出重定向

一、.输出重定向: 1.以覆盖方式把正确输入和错误输入都保存在同一个文件中 命令 &> 文件 2.以追加方式把正确输入和错误输入都保存在同一个文件中 命令 &>> 文件 3.以追加方式把正确输入保存在文件1中,把错误输入保存在文件2中 命令 …

不止JDK7的HashMap,JDK8的ConcurrentHashMap也会造成CPU 100%

大家可能都听过JDK7中的HashMap在多线程环境下可能造成CPU 100%的现象,这个由于在扩容的时候put时产生了死链,由此会在get时造成了CPU 100%。这个问题在JDK8中的HashMap获得了解决。其实JDK7中的HashMap在多线程环境下不止只有CPU 100%这一共怪异现象&am…

关于发布DIPS的MVC项目的IIS 7.0环境配置的方法

本人技术笨拙,今天在发布DIPS的MVC4.0项目,并部署到IIS上,遇到各种问题。在查询相关资料后,最终得以解决,所以想把这个过程记录下来。 注:DIPS为一种非关系型数据库 首先,需要安装和注册DIPS。注…

Veket PuppyLinux系统装在U盘中

在碎片化或移动式办公的需求前,怎样才能做到只借助别人的硬件,而使用的是自己的操作系统以及保存数据呢?此时你可能会想到将某个Linux的桌面版本推送并存放在U盘中,便于按需进行启动与使用。 Veket是基于Puppy的一个Linux简体中文…

Java调优:Mybaitis的缓存优化

作者:肥朝,来自肥朝(ID:feichao_java)我们先来看代码这段代码中, Mybatis一共发了两条SQL,这就好像说, Mybatis中没有缓存,然后我们打开Mybatis的文档一看,顿时震惊这难道是骗人的,说好的默认开启缓存呢…..其实不是的…

扩充swap空间的两种方法

扩充swap空间的两种方法:方法一:分区的形式#fdisk /dev/sdb ---> t ---> 82--->w#mkswap /dev/sdb1 (格式化swap分区) mkswap-c检查是否有坏损块check#swapon /dev/sdb1 (启用swap分区) -L指定swap的卷标名称…

Shell编程之多命令顺序执行和管道符

1.多命令顺序执行: 打开!命令终端: 2.管道符 打开命令终端:

PowerShell3.0入门视频(由Jeffrey Snover和Jason Helmick主讲)

视频是在微软虚拟学院上,可注册观看:http://www.microsoftvirtualacademy.com/training-courses/796?o5590视频分10章:1.克服对shell的恐惧2.帮助系统3.使用管道连接和扩展shell4.用于管理的对象5.深入探讨管道6.在shell中使用powershell&am…

阿里一面 缓存穿透、缓存击穿、缓存雪崩和热点数据失效问题的解决方案

作者:乔二爷,来自:乔二爷(ID:hellozhouq)1 前言昨天晚上接到阿里的电面电话,过程中就问到了关于缓存相关的问题。虽然以前接触过,多多少少了解了一些。但是之前自己并没有好好记录这…

Fix chrome 下flash crash的问题

2019独角兽企业重金招聘Python工程师标准>>> 本来好好的,结果不知道为什么,在MAC下使用chrome不断出现flash插件的错误,网上搜了一下,看这里,要把chrome自带的flash插件注释掉。重启chrome好象是没什么问题…

为什么阿里巴巴建议集合初始化时,指定集合容量大小?

集合是Java开发日常开发中经常会使用到的。在之前的一些文章中,我们介绍过一些关于使用集合类应该注意的事项,如《为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作》。关于集合类,《阿里巴巴Java开发手册》中其实还有另外一个…

十五、Python操作mysql数据库

利用Navicat Premium 15软件连接mysql数据库,新建testdb数据库,并添加2个表usertest和userinfo。 main.py #!/usr/bin/python3 # -*- coding: utf-8 -*- import reimport pymysql # 导入模块myConn pymysql.connect(host127.0.0.1, # 主机模块port33…

闪存必须解决的三大问题

数据即商机——LSI公司首次在美国之外举行的加速技术创新(AIS)峰会的主题道出了大数据的价值所在。对实时处理能力要求极高的大数据,要求存储也必须做出改变,这也是为什么闪存在数据中心里越来越受欢迎的原因。与硬盘共存SSD刚进入…