JAVA基础面试题(第十一篇)上! JVM

Hello好久不见!,最近我们讲更新JVM部分的面试题。
JVM 这块比较难理解,而且也是不擅长的点。所以今天我更新一下JVM希望小伙伴们能在面试中取得好成绩!

JVM

1. 什么是JVM内存结构?

在这里插入图片描述
jvm将虚拟机分为5大区域,程序计数器、虚拟机栈、本地方法栈、java堆、方法区;

  • 程序计数器:线程私有的,是一块很小的内存空间,作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址;
  • 虚拟机栈:线程私有的,每个方法执行的时候都会创建一个栈帧,用于存储局部变量表、操作数、动态链接和方法返回等信息,当线程请求的栈深度超过了虚拟机允许的最大深度时,就会抛出StackOverFlowError;
  • 本地方法栈:线程私有的,保存的是native方法的信息,当一个jvm创建的线程调用native方法后,jvm不会在虚拟机栈中为该线程创建栈帧,而是简单的动态链接并直接调用该方法;
  • 堆:java堆是所有线程共享的一块内存,几乎所有对象的实例和数组都要在堆上分配内存,因此该区域经常发生垃圾回收的操作;
  • 方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据。即永久代,在jdk1.8中不存在方法区了,被元数据区替代了,原方法区被分成两部分;1:加载的类信息,2:运行时常量池;加载的类信息被保存在元数据区中,运行时常量池保存在堆中;

2. 什么是JVM内存模型?

Java 内存模型(下文简称 JMM)就是在底层处理器内存模型的基础上,定义自己的多线程语义。它明确指定了一组排序规则,来保证线程间的可见性。

这一组规则被称为 Happens-Before, JMM 规定,要想保证 B 操作能够看到 A 操作的结果(无论它们是否在同一个线程),那么 A 和 B 之间必须满足 Happens-Before 关系

  • 单线程规则:一个线程中的每个动作都 happens-before 该线程中后续的每个动作
  • 监视器锁定规则:监听器的解锁动作 happens-before 后续对这个监听器的锁定动作
  • volatile 变量规则:对 volatile 字段的写入动作 happens-before 后续对这个字段的每个读取动作
  • 线程 start 规则:线程 start() 方法的执行 happens-before 一个启动线程内的任意动作
  • 线程 join 规则:一个线程内的所有动作 happens-before 任意其他线程在该线程 join() 成功返回之前
  • 传递性:如果 A happens-before B, 且 B happens-before C, 那么 A happens-before C

怎么理解 happens-before 呢?
如果按字面意思,比如第二个规则,线程(不管是不是同一个)的解锁动作发生在锁定之前?这明显不对。happens-before 也是为了保证可见性,比如那个解锁和加锁的动作,可以这样理解,线程1释放锁退出同步块,线程2加锁进入同步块,那么线程2就能看见线程1对共享对象修改的结果。

在这里插入图片描述
Java 提供了几种语言结构,包括 volatile, final 和 synchronized, 它们旨在帮助程序员向编译器描述程序的并发要求,其中:

  • volatile - 保证可见性和有序性
  • synchronized - 保证可见性和有序性; 通过管程(Monitor)\保证一组动作的原子性
  • final - 通过禁止在构造函数初始化和给 final 字段赋值这两个动作的重排序,保证可见性(如果 this 引用逃逸就不好说可见性了)

编译器在遇到这些关键字时,会插入相应的内存屏障,保证语义的正确性。

有一点需要注意的是,synchronized 不保证同步块内的代码禁止重排序,因为它通过锁保证同一时刻只有一个线程访问同步块(或临界区),也就是说同步块的代码只需满足 as-if-serial 语义 - 只要单线程的执行结果不改变,可以进行重排序。

所以说,Java 内存模型描述的是多线程对共享内存修改后彼此之间的可见性,另外,还确保正确同步的 Java 代码可以在不同体系结构的处理器上正确运行。

3. heap 和stack 有什么区别?

(1)申请方式

stack:由系统自动分配。例如,声明在函数中一个局部变量 int b; 系统自动在栈中为 b 开辟空间

heap:需要程序员自己申请,并指明大小,在 c 中 malloc 函数,对于Java 需要手动 new Object()的形式开辟

(2)申请后系统的响应

stack:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

heap:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

(3)申请大小的限制

stack:栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS 下,栈的大小是 2M(默认值也取决于虚拟内存的大小),如果申请的空间超过栈的剩余空间时,将提示 overflow。因此,能从栈获得的空间较小。

heap:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的, 自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见, 堆获得的空间比较灵活,也比较大。

(4)申请效率的比较

stack:由系统自动分配,速度较快。但程序员是无法控制的。

heap:由 new 分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

(5)heap和stack中的存储内容

stack:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址, 然后是函数的各个参数,在大多数的 C 编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。

当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

heap:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

4. 什么情况下会发生栈内存溢出?

除了程序计数器,其他内存区域都有 OOM 的风险。

  • 栈一般经常会发生 StackOverflowError,比如 32 位的 windows 系统单进程限制 2G 内存,无限创建线程就会发生栈的 OOM
  • Java 8 常量池移到堆中,溢出会出 java.lang.OutOfMemoryError: Java heap space,设置最大元空间大小参数无效;
  • 堆内存溢出,报错同上,这种比较好理解,GC 之后无法在堆中申请内存创建对象就会报错;
  • 方法区 OOM,经常会遇到的是动态生成大量的类、jsp 等;
  • 直接内存 OOM,涉及到 -XX:MaxDirectMemorySize 参数和 Unsafe 对象对内存的申请。

排查 OOM 的方法:

  • 增加两个参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof,当 OOM 发生时自动 dump 堆内存信息到指定目录;
  • 同时 jstat 查看监控 JVM 的内存和 GC 情况,先观察问题大概出在什么区域;
  • 使用 MAT 工具载入到 dump 文件,分析大对象的占用情况,比如 HashMap 做缓存未清理,时间长了就会内存溢出,可以把改为弱引用 。

6. 谈谈 JVM 中的常量池?

JVM常量池主要分为Class文件常量池、运行时常量池,全局字符串常量池,以及基本类型包装类对象常量池

  • Class文件常量池。class文件是一组以字节为单位的二进制数据流,在java代码的编译期间,我们编写的java文件就被编译为.class文件格式的二进制数据存放在磁盘中,其中就包括class文件常量池。
  • 运行时常量池:运行时常量池相对于class常量池一大特征就是具有动态性,java规范并不要求常量只能在运行时才产生,也就是说运行时常量池的内容并不全部来自class常量池,在运行时可以通过代码生成常量并将其放入运行时常量池中,这种特性被用的最多的就是String.intern()。
  • 全局字符串常量池:字符串常量池是JVM所维护的一个字符串实例的引用表,在HotSpot VM中,它是一个叫做StringTable的全局表。在字符串常量池中维护的是字符串实例的引用,底层C++实现就是一个Hashtable。这些被维护的引用所指的字符串实例,被称作”被驻留的字符串”或”interned string”或通常所说的”进入了字符串常量池的字符串”。
  • 基本类型包装类对象常量池java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外上面这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象。

7. 如何判断一个对象是否存活?

判断一个对象是否存活,分为两种算法1:引用计数法;2:可达性分析算法;

  • 引用计数法: 给每一个对象设置一个引用计数器,当有一个地方引用该对象的时候,引用计数器就+1,引用失效时,引用计数器就-1;当引用计数器为0的时候,就说明这个对象没有被引用,也就是垃圾对象,等待回收; 缺点:无法解决循环引用的问题,当A引用B,B也引用A的时候,此时AB对象的引用都不为0,此时也就无法垃圾回收,所以一般主流虚拟机都不采用这个方法;

  • 可达性分析法 从一个被称为GC Roots的对象向下搜索,如果一个对象到GC Roots没有任何引用链相连接时,说明此对象不可用,在java中可以作为GC Roots的对象有以下几种:

    • 虚拟机栈中引用的对象
    • 方法区类静态属性引用的变量
    • 方法区常量池引用的对象
    • 本地方法栈JNI引用的对象

但一个对象满足上述条件的时候,不会马上被回收,还需要进行两次标记;第一次标记:判断当前对象是否有finalize()方法并且该方法没有被执行过,若不存在则标记为垃圾对象,等待回收;若有的话,则进行第二次标记;第二次标记将当前对象放入F-Queue队列,并生成一个finalize线程去执行该方法,虚拟机不保证该方法一定会被执行,这是因为如果线程执行缓慢或进入了死锁,会导致回收系统的崩溃;如果执行了finalize方法之后仍然没有与GC Roots有直接或者间接的引用,则该对象会被回收;

总结:JVM希望大家仔细看看,这只是一部分。我们分三部分来更新。

多谢大家支持!!!

如果没看过前几篇的文章的,可以点击链接去看看,如果方便可以点赞收藏,给我点个关注,创作不易!

JAVA基础面试题(第十篇)下! 集合与数据结构

JAVA基础面试题(第九篇)中! 集合与数据结构

JAVA基础面试题(第八篇)上! 集合与数据结构

JAVA基础面试题(第七篇)!异常

JAVA基础面试题(第六篇)!序列化与IO流

JAVA基础面试题(第五篇)!反射与泛型

JAVA基础面试题(第四篇)!equal、hashcode及String解析

JAVA基础面试题(第三篇)!面向对象

JAVA基础面试题(第二篇)!基础语法与关键字

JAVA基础面试题(第一篇)!

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

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

相关文章

上市公司-库存周转率、供应链效率明细数据集(2000-2022年)

01、数据介绍 库存周转率是衡量企业库存管理效率的关键指标之一,它反映了企业库存的流转速度。而供应链效率则体现了企业在整个供应链管理中的表现,包括采购、生产、物流等环节的协同和优化。 提高库存周转率和供应链效率是上市公司优化企业运营和管理…

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2

ICode国际青少年编程竞赛- Python-2级训练场-识别循环规律2 1、 for i in range(3):Dev.step(3)Dev.turnRight()Dev.step(4)Dev.turnLeft()2、 for i in range(3):Spaceship.step(3)Spaceship.turnRight()Spaceship.step(1)3、 Dev.turnLeft() Dev.step(Dev.x - Item[1].…

编译和链接(超详细)

✅博客主页:爆打维c-CSDN博客​​​​​​ 🐾 🔹分享c语言知识及代码 一、编译和链接实例 假设我们有一个名为main.c的C语言源文件,它包含了一个简单的Hello World程序。我们可以使用gcc编译器对该源文件进行编译,生成一个可执行…

AI大模型探索之路-训练篇18:大语言模型预训练-微调技术之Prompt Tuning

系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知 AI大模型探索之路-训练篇2:大语言模型预训练基础认知 AI大模型探索之路-训练篇3:大语言模型全景解读 AI大模型探索之路-训练篇4:大语言模型训练数据集概…

亚马逊是如何铺设多个IP账号实现销量大卖的?

一、针对亚马逊平台机制,如何转变思路? 众所周知,一个亚马逊卖家只能够开一个账号,一家店铺,这是亚马逊平台明确规定的。平台如此严格限定,为的就是保护卖家,防止卖家重复铺货销售相同的产品&a…

【读论文】Gaussian Grouping: Segment and Edit Anything in 3D Scenes

Gaussian Grouping: Segment and Edit Anything in 3D Scenes 文章目录 Gaussian Grouping: Segment and Edit Anything in 3D Scenes1. What2. Why3. How3.1 Anything Mask Input and Consistency3.2 3D Gaussian Rendering and Grouping3.3 Downstream: Local Gaussian Editi…

10000 字详细讲解 Spring 中常用注解及其使用

如下图京东购物页面,当我们选择点击访问某一类商品时,就会向后端发起 HTTP 请求,当后端收到请求时,就会找到对应的代码逻辑对请求进行处理,那么,后端是如何来查找处理请求相对应的代码呢?答案就…

计算机考研|25人太难了,408会炸,还是自命题会炸?

自命题已经不是炸不炸的问题了,是有没有学上的问题。 我记得去年九月一些学校宣布改考408的时候,整个群里都炸了,同学一片哀嚎。要知道九月的时候要重新准备408肯定是不可能了,一来408复习的基础阶段已经过去了,二来英…

人工智能哪些大学比较好

人工智能领域的大学有很多,以下是一些国际上被广泛认可的一流大学: 1. **斯坦福大学(Stanford University)** - 位于美国加州的斯坦福大学拥有顶尖的人工智能研究中心,并在机器学习、自然语言处理等领域处于领先地位。…

phpstudy(MySQL启动又立马停止)问题的解决办法

方法一:查看本地安装的MySQL有没有启动 1.鼠标右击开始按钮选择计算机管理 2.点击服务和应用程序 3.找到服务双击 4.找到MySQL服务 5.双击查看是否启动,如启动则停止他,然后确定,重新打开phpstudy,启动Mysql. 方法二&#xff…

[鸟哥私房菜]4.首次登录与在线求助

第4章 首次登录与在线求助 4.1.3 X Window 与命令行模式的切换 通常我们称命令行界面为终端界面、Terminal 或 Console。Linux 默认的情况下会提供六个终端(Terminal)来让用户登录, 切换的方式为使用:[Ctrl] [Alt] [F1]~[F6] …

TypeScript学习日志-第十七天(泛型约束)

泛型约束 当我们使用泛型时非常方便,但是在使用的过程中也会遇到很多问题,如图: 这时候就会提示错误,因为返回的是相加的值,但是不是所有的类型都能相加的,例如来个undefined类型的 就不能进行相加了&…

回顾5款我非常喜欢的软件,希望大家也能喜欢

​ 我喜欢分享好软件,这就像与老友聊天一样让我感到快乐。在这个过程中,我可以回顾这些实用的小工具,也希望它们可以帮助到更多人。 1.备份工具——Cobian Backup ​ Cobian Backup是一款功能强大的备份软件,支持自动定时备份、增量备份、差异备份等多种备份方式。…

wePWNise:一款功能强大的红队Office宏VBA代码生成工具

关于wePWNise wePWNise是一款功能强大的Office宏VBA代码生成工具,该工具基于纯Python开发,可以帮助广大研究人员生成用于Office宏或模版的VBA代码,并以此来测试目标Office环境、应用程序控制和防护机制的安全性。 wePWNise的设计理念将自动化…

libcity 笔记:基本使用方法

介绍 — Bigscity-LibCity 文档 (bigscity-libcity-docs.readthedocs.io) 1 介绍 一个统一、全面、可扩展的代码库,为交通预测领域提供了一个可靠的实验工具和便捷的开发框架目前支持 交通状态预测 交通流量预测 交通速度预测 交通需求预测 起点-终点&#xff…

Baidu Comate智能编码助手:大学生的代码编写助手

Baidu Comate智能编码助手:大学生的代码编写助手 前言一、关于Baidu Comate智能编码助手1.1 Baidu Comate智能编码助手简介1.2 产品功能 二、安装使用(本文以pycharm为例)三、我的百度Comate之旅3.1智能推荐3.1.1 单行推荐3.1.2 多行推荐 3.2…

pg数据库学习知识要点分析-1

知识要点1 对象标识OID 在PostgreSQL内部,所有的数据库对象都通过相应的对象标识符(object identifier,oid)进行管理,这些标识符是无符号的4字节整型。数据库对象与相应oid 之间的关系存储在对应的系统目录中&#xf…

AI论文速读 |2024[IJCAI]TrajCL: 稳健轨迹表示:通过因果学习隔离环境混杂因素

题目: Towards Robust Trajectory Representations: Isolating Environmental Confounders with Causal Learning 作者:Kang Luo, Yuanshao Zhu, Wei Chen, Kun Wang(王琨), Zhengyang Zhou(周正阳), Sijie Ruan(阮思捷), Yuxuan Liang(梁宇轩) 机构&a…

SAP-PP-MM特殊库存的生产发料

如果有个物料是在特殊库存E,那么往生产订单发料是如何确定哪一个组件消耗这个特殊库存呢? 在生产订单中有哪些标记确定特殊库存?确定销售订单和行项目? 通过上图可以看到特殊库存标记1,也就是单独客户库存。 其他的特…

洗地机什么品牌好?洗地机怎么选?618洗地机选购指南

随着科技的飞速发展,洗地机以其高效的清洁能力、稳定的性能和用户友好的设计而闻名,不仅可以高效吸尘、拖地,还不用手动洗滚布,已经逐渐成为现代家庭不可或缺的清洁助手。然而,在众多品牌和型号中,如何选择…