Java面经-jvm虚拟机_wonderful land的博客-程序员宅基地_java虚拟机面经

技术标签: 面试  java虚拟机  java面经  

JVM复习重点(待续)

1. JVM的主要组成部分和作用

JDK1.8之前:

1)运行时数据区域:

程序计数器和虚拟机栈和本地方法栈都是线程私有的。

  • 程序计数器:
    • 线程执行java代码时,存放虚拟机字节码的指令地址,执行Native代码时,值为空。可以看着做字节码的行号指示器。
  • Java虚拟机栈:
    • 每个虚拟机栈执行方法执行时也会创建线程私有的栈帧。
    • 存放java方法执行的内存模型。栈帧:局部变量表,操作数栈,动态链接,方法出口。
      • 局部变量表存放了编译器可知的八种数据类型和对象引用。
    • 局部变量表存放基本数据类型、对象引用、returnAddress类型。
  • 本地方法栈:
    • 为Native方法提供服务。

Java的堆、方法区都是线程共享的。

  • Java堆:

    • 存放对象实例和数组。
    • 垃圾回收的主要区域,称为GC堆,采用分代收集算法,分为新生代和老年代
  • 方法区:

    • 存放加载的类信息常量静态变量(以static修饰的变量和方法)、即时编译器编译的代码。
    • 运行时常量池是方法区的一部分。存放编译器生成的各种字面量符号引用

    (这个和堆中的字符串常量池有什么关系?应该是上述常量的一部分)

  • 虚拟机规范可以选择不实现垃圾收集。

2)本地库接口:与本地库接口交互

3)类加载器:根据类的全限定名,将类装载到方法区

4)执行引擎:包括JIT编译器和GC垃圾回收器。

JDK 1.8及之后, 方法区被元空间(Metaspace)取代,是直接内存的一部分。

一个java指令的运行过程:

Java代码(.java)-编译器javac - 字节码文件(.class)- 类加载器 - 内存方法区并封存一个类对象 - 执行引擎翻译 - 底层指令

堆栈的区别:

  • 物理地址:堆不连续、栈连续
  • 内存:堆的内存分配到运行期确定,大小不固定;栈是连续的,分配的大小在编译器确定
  • 内容:栈存放局部变量、操作数栈、返回值,堆存放对象的实例和数组。
  • 注意,静态变量和静态方法位于方法区,但是其所在类的对象依然位于堆。
2. (HotSpot虚拟机中)对象的创建:
  • 类加载:指令中的参数是否能在堆中的常量池中定位到一个类的符号引用。没有,执行类加载。
  • 堆中分配空间:对象所需的内存在类加载这一步就可以确定,通过指针碰撞法或者空闲列表法在堆中分配空间。
  • 保证安全:使用两种方式保证划分空间的动作是安全的。
  • 初始化:将分配到的空间初始化为零值。
  • 写入对象头:将对象是那个类的实例,如何找到类的元数据信息、对象哈希码、对象的GC分代信息写入对象头
  • 执行init方法。

注意:init是实例构造器,调用实例的构造方法;clinit是类构造器。

对象在内存中存储的布局可以分为三部分:对象头、实例数据和对齐填充。其中对象头又包括两部分,一部分是运行时信息:hash码、GC分代信息、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳;另一部分是类型指针,指向类的元数据(位于方法区)。

3.为对象分配内存

指针碰撞法:Java堆是规整的,用过的在一边,空闲的在另一边,分配内存时将指针指示器向空闲一端移动和对象大小相等的距离。

空闲列表法:如果Java堆不是规整的,需要由虚拟机维护一个列表来记录哪些内存可用,需要的时候,从列表中查询合适的内存分配给对象,更新列表记录。。

Java堆是否规整由Java使用的垃圾回收器是否带有压缩功能决定,如:标记-整理法的Java堆就是规整的。

4.处理并发安全问题

对象的创建在并发条件下会导致线程的不安全(原因看单例模式)。两种解决方法:

  • 对分配内存空间的动作进行同步处理(CAS+失败重试来保证操作的原子性)

  • 内存分配按照线程划分在不同空间中进行,每个线程在Java堆中预先分配内存,叫“本地线程分配缓冲”

5.对象的访问定位

java程序使用栈上的reference数据来操作堆上的具体对象。

  • 句柄方式:栈的ref指向堆中的句柄池,句柄池有指向堆中对象实例和指向方法区的类型数据的指针。优点:对象实例被移动时,句柄不用修改。
  • 直接指针方式,ref直接指向堆中的对象实例,对象实例的对象头中保存指向方法区类型数据的指针。优点:快。
6.对象创建的不同方式

使用new关键字 - 调用构造函数

使用Class类的newInstance() - 调用构造函数

使用Constructor类的newInstance() - 调用构造函数

使用clone() - 没有调用构造函数

使用反序列化 - 没有调用构造函数

7.简述垃圾回收机制

Java中不需要显式释放对象内存,由虚拟机自动执行。GC线程是专门用于回收垃圾的线程,低优先级,在虚拟机空闲或者堆内存不足时,扫描不需要的对象,添加到待回收的集合中,执行回收。

垃圾回收机制,有效得防止了内存泄露,可以有效地使用可以使用得内存。

8.确认哪些对象可以回收的算法
  • 引用计数法。有一个地方引用,引用计数+1;引用失效,引用计数-1;(很难解决对象之间的循环引用问题)
  • 可达性算法。设定GCroot,从节点往下搜索,搜索走过的路径称为引用链。当一个对象到GCroot没有引用链,称这个对象不可达。
    • GC Roots对象有:
      • 虚拟机栈中(本地变量表)中引用的对象。
      • 方法区中类静态变量引用的对象。
      • 方法区中常量引用的对象。
      • Native方法引用的对象。

引用可以分为:强引用、软引用、弱引用、虚引用

9.永久代(方法区)的垃圾回收

垃圾回收主要发生在堆区,其实方法区也有垃圾回收。永久代的回收主要包括废弃常量和无用的类。永久代满了或者超过临界值,会触发Full GC完全垃圾回收。(JDK8 中移除了永久代,新加了叫元数据区的native内存区)

10.垃圾回收算法:
  • 标记-清除算法:先标记,后清除。缺点:会产生大量的内部碎片。
  • 复制算法:将内存按照容量分为两块,每次将存活的对象复制到另一块上。(新生代)
  • 标记-整理算法:先标记,再清除,后整理,让存活的对象往一侧移动,清理掉端边界以外的内存。
  • 分代收集算法:新生代使用复制算法(死亡率高),老年代使用标记算法。

HotSpot的垃圾回收机制的实现:

  • 使用OopMap数据结构记录所有GC Roots。
  • 只有在安全点才生成OopMap,进入GC。
11.分代收集算法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GfKAkm36-1623304051849)(Java虚拟机第二版.assets/虚拟机分代算法.png)]

新生代-老年代-永久代 。新生代:老年代 = 1:2;新生代中的Eden: To Survivor: From Survivor = 8:1:1.

对象的分配主要在堆上,主要在Eden区,如果启动了本地线程分配缓冲,则优先分配在TLAB上。

对象优先在新生代的Eden区分配,当Eden区没有足够空间分配时,就会发起一次Minor GC;如果Minor GC后还是没有足够的空间,启动分配担保机制在老年代中分配内存。

如果对象在Eden区出生,能被Survivor容纳,将进入Survivor空间,对象年龄+1.

大对象直接在老年代分配。因为新生代是复制算法,这样可以避免大对象在新生代反复复制。

长期存活的对象将进入老年代。

12.分代垃圾回收算法
  • 把 Eden + From Survivor 存活的对象放入 To Survivor 区;

  • 清空 Eden 和 From Survivor 分区;

  • From Survivor 和 To Survivor 分区交换。

  • 每次gc在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。

关于Minor GC 和 Full GC

  • 发生在新生代的GC,频繁,速度快
  • 发生在老年代的GC,至少伴随一次Minor GC,速度很慢。一般使用标记-整理算法。
13.class文件中包含的内容
  • 常量池

  • 访问标志

  • 类索引、父类索引、接口索引集合

  • 字段表集合

常量池可以理解为class文件中的资源仓库。

常量池中存放了两大类常量:字面量和符号引用。

其中,字面量包括:

  • 文本字符串
  • 声明为final的常量值。

符号引用包括:

  • 类和接口的全限定名。
  • 字段的名称和描述符。
  • 方法的名称和描述符。

字段表集合:包括了类级变量和实例级变量

字段可以包含的信息:作用域、类还是实例变量(static)、可变性(final)、并发可见性(volatile)、可被序列化(transient)、字段数据类型。

14. 必须进行类初始化的几种情况(初始化一定会导致类加载)

Java语言,动态可拓展,先编译成class字节码文件,在运行时再执行动态加载(加载到jvm)和动态链接

java的一个class文件对应一个类或者一个接口,类的生命周期一般包括加载、验证、准备、解析、初始化、使用、卸载。

JVM规范规定了初始化的几种情况,加载、验证、准备一定要在此之前。

​ ①new一个对象;读取或者设置一个类的静态字段(final修饰的常量在编译期放入常量池,除外),调用类的静态方法

​ ②使用reflect包反射调用

​ ③调用一个类时发现其父类没有初始化

​ ④main所在的类

​ ⑤Methodhandle

其余的引用方式都不会发生初始化,称为被动引用。而上述导致初始化的方式称为主动引用。

15. java类加载

Java的类加载机制,指的是JVM把类的数据从Class文件加载到内存方法区,并且对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接只用的java类型。

加载:

① 通过类的全限定名获得二进制字节流(zip包、class文件、网络、动态代理技术)(这一步是由类加载器决定的)

②将类的静态存储结构转为方法区的运行时数据结构。

③生成代表这个类的Class对象,作为方法区这个类的各个数据的返回入口。

验证:

文件格式、元数据、字节码、符号引用验证

准备:

给类变量(static修饰的静态变量)在方法区分配内存并且初始化为0。

解析:

将常量池中的符号引用替换为直接引用的过程。

初始化:

真正执行字节码,执行类构造器()方法,收集类变量的赋值动作和静态语句块合并而成。(和实例构造器不同,不需要显式调用父类构造器)

16.四种类加载器
  • 启动类加载器:用于加载Java核心类库
  • 扩展类加载器:用于加载Java扩展库
  • 应用程序类加载器:根据全类名加载Java类
  • 自定义类加载器:继承自java.lang.ClassLoader
17.双亲委派模型

上述四种加载器是父类和子类继承的关系。每一个类+其类加载器,一起确定了在JVM的唯一性。

双亲委派模型:一个类加载器获得类加载请求,不会自己加载这个类,而是把这个请求委派给父类。当传送到最顶层,只有当最顶层的加载器无法完成加载时,子加载器才会加载这个类。

用父类构造器)

16.四种类加载器
  • 启动类加载器:用于加载Java核心类库
  • 扩展类加载器:用于加载Java扩展库
  • 应用程序类加载器:根据全类名加载Java类
  • 自定义类加载器:继承自java.lang.ClassLoader
17.双亲委派模型

上述四种加载器是父类和子类继承的关系。每一个类+其类加载器,一起确定了在JVM的唯一性。

双亲委派模型:一个类加载器获得类加载请求,不会自己加载这个类,而是把这个请求委派给父类。当传送到最顶层,只有当最顶层的加载器无法完成加载时,子加载器才会加载这个类。

好处:保证Java运作的稳定性。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_48214777/article/details/117777519

智能推荐

python 逻辑回归结果_Python----逻辑回归_weixin_39833270的博客-程序员宅基地

#导入标注库importnumpy as npimportmatplotlib.pyplot as pltimportpandas as pd#导入数据dataset = pd.read_csv('Data.csv')X= dataset.iloc[:, [2,3]].valuesy= dataset.iloc[:, 4].values#将导入的数据集分为训练集和测试集from sklearn.m...

第一次使用Markdown编辑器自带的全部提示_一筐兔子的博客-程序员宅基地_markdown提示

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

linux查看u盘的盘名,Linux下判断磁盘属于U盘、HDD盘或者SSD盘的方法_爱古丽的博客-程序员宅基地

问题背景由于项目需要,在自动化安装系统时,智能过滤掉U盘以及固态盘(SSD),因此需要判断出各磁盘类型,然后将其忽略掉。列出系统中可用的磁盘通过以下命令,可以找出当前系统可用的所有磁盘:[[email protected] ~]# cat /proc/partitions|grep "^[^a-zA-Z].*[^0-9]$"|awk '{print $4}'sdasdbsdc[[email protected]

Transmit 5.5.1 for Mac 中文共享版 – 优秀的FTP文件上传下载客户端_weixin_30414155的博客-程序员宅基地

下载地址:风云社区macOS文件传输应用程序的黄金标准刚刚推向未来。Transmit 5.5.1 在这里。使用简单,熟悉且功能强大的UI上传,下载和管理大量服务器上的文件。更多服务器:Transmit 5 有更多服务器。Transmit现在连接到11个新的云服务,如Backblaze B2,Box,Google Drive,DreamObjects,Dropbox,Microsof...

Varnish 问题点 与 技术方案 Varnish 优劣分析_装B五分钟,挨打两小时的博客-程序员宅基地

A10 有没有能做热点统计1 Varnish 分布式 HA (目前没有HA)2 Varnish 热点监控 (建议热点需要外部插件统计,API的话目前并木有发现,但是他自带一个伪热点功能)如果用外部插件统计热点。热点的读写Varnish比较有难度。Varnish是VCL语言编写。而配置文件使用C语言方法。Varnish的优势Varnih 的对比Squi...

Day-18-购物车模块的实现,商品的加购和删除,登录以后才可以查看购物车,订单等_香瓜西蕉的博客-程序员宅基地_html 商品列表

购物车模块的实现1-编辑POJO对象@TableName("tb_cart")@[email protected](chain = true)public class Cart extends BasePojo{ @TableId(type = IdType.AUTO) private Long id; private Long userId; private Long itemId; private String itemTitle; priv

随便推点

串口 多个activity 安卓_安卓 4个串口助手 源码 及APK_yo xiba的博客-程序员宅基地

【实例简介】安卓 串口APK 及eclipse源码,可以同时打开4个串口,可以支持到安卓5.1以上的版本;可支持串口串接,防止有些硬件串口数据接收后分行;【实例截图】【核心代码】android_4ComsAssistant_code-source_V1.2_20190325└── ComAssistant├── AndroidManifest.xml├── bin│ ├── AndroidMa...

Linux安装openoffice_流浪的眼圈的博客-程序员宅基地_linux离线安装openoffice

下载cd /usr/local/toolswget https://jaist.dl.sourceforge.net/project/openofficeorg.mirror/4.1.7/binaries/zh-CN/Apache_OpenOffice_4.1.7_Linux_x86-64_install-rpm_zh-CN.tar.gz解压安装tar xf Apache_OpenOffice_4.1.7_Linux_x86-64_install-rpm_zh-CN.tar.gzcd ...

WebGL2系列之顶点数组对象_weixin_34138255的博客-程序员宅基地

使用了顶点缓冲技术后,绘制效率有了较大的提升。但是还有一点不尽如人意,那就是顶点的位置坐标、法向量、纹理坐标等不同方面的数据每次使用时需要单独指定,重复了一些不必要的工作。WebGL2提供了一种专门用于解决此问题的对象——顶点数组对象(VAO)。本节将介绍顶点数组对象。顶点数组对象,在WebGL1中,是一个扩展对象,该扩展对象的名称是O...

警告NameVirtualHost *:80 has no VirtualHosts的原因_shanliangliuxing的博客-程序员宅基地

转自:http://hi.baidu.com/monton/item/43d22372084e9046ee1e532a引起这个警告的原因是NameVirtualHost语法错误 ,对于同一主机支持多个虚拟主机的情况,只需要命名一次NameVirtualHost,如果在每个虚拟主机配置文件中都加上NameVirtualHost *:80 ,则会报这个警告。

cacti安装与配置_ygmdream的博客-程序员宅基地

一、准备所需要的软件包Apache     http://www.apache.org/Mysql      http://www.mysql.com/Php        http://www.php.netRrdtool    http://oss.oetiker.ch/rrdtool/Net-snmp   http://www.net-snmp.org

推荐文章

热门文章

相关标签