【面经】讲一下你对jvm和jmm的了解
JVM
JVM是Java虚拟机,是Java程序的执行环境。它是一种虚拟的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现.
JVM是Java程序运行的核心,可以将Java字节码转换为可执行的机器码,提供了跨平台性、优秀的垃圾回收器,以及可靠的即时编译器
JVM内存结构
JVM通过程序计数器、虚拟机栈、本地方法栈、堆、方法区来管理内存和执行线程。
程序计数器–用于记录当前执行的字节码指令的行号,
虚拟机栈–用于存储每个方法的调用信息,
本地方法栈–用于存储本地方法的调用信息,
堆—用于存储对象实例和数组
方法区—用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
变量存储的位置取决于其类型和存储方式。
在Java中,基本类型(如int、char、boolean等)的值是存储在栈(Stack)中的,
而引用类型(如String、Object等)的值则是存储在堆(Heap)中的
JVM中,线程共享的内存区域—堆(Heap)和方法区(Metaspace);
线程私有的内存区域----程序计数器(Program Counter Register)、Java虚拟机栈(Java Virtual Machine Stack)和本地方法栈(Native Method Stack)
JDK 8之前的永久代不是方法区。
永久代(PermGen)是Java内存区域的一个特殊部分,主要用于存储类的元数据信息、常量池、静态变量等。
而方法区(Method Area)是另一个Java内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
虽然永久代和元空间都存储类的元数据信息,但它们在JDK 8之后被合并,并被称为元空间(Metaspace)。
在JDK 1.8下,JVM的内存结构发生了变化,引入了元空间(Metaspace)的概念,以替代之前的永久代(PermGen)。
元空间位于堆内存之外,用于存储类的元数据,它的最大空间大小默认情况下与老年代一样大,但可以通过JVM参数进行设置。元空间的出现解决了永久代中存在的一些问题,如GC无法清理永久代中等问题。
在JDK 1.8下,JVM的内存结构如下:
- 程序计数器:线程私有,用于记录当前执行的字节码指令的行号。
- Java虚拟机栈:线程私有,在方法执行时会创建一个栈帧,该栈帧包括了局部变量表、操作数栈、动态链接、方法出口等信息。
- 本地方法栈:线程私有,用于存储本地方法的调用信息。
- 堆:线程共享,用于存储对象实例和数组。在JDK 1.8中,堆内存被细分为新生代和老年代。
- 元空间:线程共享,用于存储类的元数据。元空间位于堆内存之外,它的最大空间大小可以通过JVM参数进行设置。
从Java 8开始,堆内存被细分为新生代和老年代,其中新生代又分为Eden区和两个Survivor区(Survivor0和Survivor1),这些区域都是所有线程共享的.
JVM内存参数配置
JVM的内存区域大小可以通过启动参数进行调整。例如,可以使用-Xms和-Xmx选项来设置堆的初始化和最大值。此外,还可以使用-XX:PermSize和-XX:MaxPermSize选项来调整永久代(在JDK8及以前使用)或元空间(Metaspace,JDK8以后使用)的初始化和最大值。
具体来说,可以按照以下步骤进行调整:
- 根据应用程序的需求确定堆内存的大小。例如,可以将-Xms和-Xmx选项设置为相同的大小,以充分利用系统内存。
- 根据物理内存的大小调整-Xms和-Xmx的值。例如,如果物理内存为4G,可以将-Xms和-Xmx的值设置为2G。
- 根据应用程序的特点选择适合的内存区域大小调整策略。例如,如果应用程序在大负载情况下会急剧地占用更多的内存,那么可能需要将-Xms和-Xmx的值设置得更大一些。
- 如果应用程序使用了永久代或元空间,也需要调整相应的内存区域大小。例如,可以使用-XX:PermSize和-XX:MaxPermSize选项来调整永久代的初始化和最大值,使用-XX:MetaspaceSize和-XX:MaxMetaspaceSize选项来调整元空间的初始化和最大值。
需要注意的是,在调整内存区域大小时,需要综合考虑系统的可用内存、物理内存的限制以及应用程序的需求等因素。如果设置的值过大,可能会导致系统崩溃或者出现其他问题;如果设置的值过小,则会影响应用程序的性能和稳定性。因此,需要进行适当的调整和测试,以找到最合适的值。
GC算法
垃圾回收(GC)是JVM自动管理内存的重要机制之一。它自动回收不再使用的对象占用的内存,以便重新分配给其他对象使用。
垃圾回收算法主要有两种:标记-清除(Mark-Sweep)和复制(Copying)。
标记-清除算法标记出所有活跃的对象,然后清除未被标记的对象。
复制算法将可用的内存空间划分为两个区域,一部分被标记为正在使用,另一部分被标记为未使用。当对象不再被使用时,它们将被移动到未使用的区域,并释放正在使用的内存空间。
什么是Full GC
Full GC是Java虚拟机中的一种垃圾回收方式。它会在整个堆空间中执行垃圾回收,清理所有不再被引用的对象所占用的内存空间。
通常,Full GC会在堆空间或者整个堆空间被占满时触发,它会清理所有的年老代对象和永久代对象。这是一种比较耗时的操作,因为它需要扫描整个堆空间,找到所有不再被引用的对象,并将它们标记为可回收的。
Full GC通常可以通过以下几种方式触发:
- 堆空间不足:当堆空间的可用空间不足以分配新对象时,会触发Full GC。在这种情况下,Full GC会清理整个堆空间。
- 调用System.gc()方法:调用System.gc()方法可以触发Full GC,虽然不能保证立即触发Full GC,但它可以提醒JVM尽快执行垃圾回收。
- 年老代空间满:当老年代空间被占满时,也会触发Full GC。如果老年代空间被占满,说明这些长时间存活的对象已经占用了大量的内存空间,需要进行Full GC来释放这些不再被引用的对象所占用的内存空间。
Full GC的作用是在JVM执行垃圾回收时对整个堆空间进行清理,释放不再被引用的对象所占用的内存空间,以便后续的对象分配。
垃圾回收器
垃圾回收器是JVM实现垃圾回收的具体工具。
不同的垃圾回收器在性能、吞吐量和内存使用等方面有所不同。
一些常见的垃圾回收器包括:Serial收集器、Parallel收集器、CMS(Concurrent Mark Sweep)收集器和G1(Garbage-First)收集器等。
Serial收集器是最简单的垃圾收集器,它在进行垃圾回收时会暂停所有其他工作线程。
Parallel收集器使用多个线程并行进行垃圾回收,以提高性能。
CMS收集器主要关注并发性,它在不影响应用程序性能的情况下进行垃圾回收。
G1收集器是一种面向停顿时间预测的收集器,它尽可能地降低垃圾收集停顿时间,并提高吞吐量
CMS是Java虚拟机中一种旧的垃圾回收器,用于执行老年代的垃圾回收。尽管CMS垃圾回收器在减小停顿时间方面表现出色,但CMS执行清理操作时可能会产生内存碎片,从而限制了老年代的可用空间,可能导致内存不足错误。CMS的并发执行会增加一定的CPU开销,因为它必须与应用程序并发运行。并且随着老年代中存活对象的增多,CMS的停顿时间可能会增加,甚至可能导致Full GC的发生
JVM调优
JVM调优主要是根据应用程序的具体需求和性能表现,调整JVM的参数和配置,以优化其性能和资源利用率。一些常见的JVM调优包括:调整堆大小、选择合适的垃圾回收器、调整线程数等。
在JDK 8及之前的版本中,可以通过以下JVM参数来调整堆的大小:
-Xms:设置JVM初始堆大小。例如,-Xms10m将初始堆大小设置为10MB。
-Xmx:设置JVM最大堆大小。例如,-Xmx20m将最大堆大小设置为20MB
选择并配置合适的垃圾回收器需要考虑多个因素,包括应用的性质、对停顿时间的要求、可用的硬件资源等。以下是一些基本建议:
- 如果应用对回收暂停时间要求不是特别高,且注重吞吐量的情况下可以选择PS收集器。
- 如果内存小于100M,使用串行收集器。
- 如果是单核、单机程序,并没有停顿时间的要求,使用串行收集器。
- 如果是多CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者JVM自己选择。
- 如果是多CPU、追求低停顿时间,需快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器。现在互联网的项目,基本都是使用G1。
要使用G1垃圾回收器,可以设置以下JVM参数:
-XX:+UseG1GC:启用G1垃圾回收器。-XX:MaxGCPauseMillis=<value>:设置每次垃圾回收的最长停顿时间,单位是毫秒。-XX:G1HeapRegionSize=<value>:设置G1堆内存中每个Region的大小,必须是2次幂,最大是32MB。-XX:G1NewSizePercent=<value>:设置新生代占整个堆内存的比例。-XX:G1MaxNewSizePercent=<value>:设置新生代最大占整个堆内存的比例。-XX:G1MixedGCCountTarget=<value>:设置触发混合回收的GC次数目标。-XX:G1MixedGCLiveThresholdPercent=<value>:设置混合回收的存活阈值比例。-XX:G1RSetUpdatingPauseTimePercent=<value>:设置RSet更新时的停顿时间占比。-XX:G1HeapWastePercent=<value>:设置堆内存浪费比例。-XX:G1MixedGCCardTableThreshold=<value>:设置卡表阈值。
这些参数可以用来调整G1垃圾回收器的行为,以满足特定的性能需求。具体参数的含义和取值范围可能会因JVM版本和操作系统环境而有所不同,因此建议在调整参数之前阅读相关文档或咨询专业人士以获取准确的信息和指导。
JMM
JMM是Java内存模型,是Java虚拟机规范中定义的一种抽象的概念。
它规定了Java程序中线程和主内存之间的抽象关系,以及在多线程环境下如何访问共享变量的规则和行为。
JMM能够确保多线程环境下的数据安全和完整性,以及提高程序的性能和可靠性
JMM是Java虚拟机实现的一部分,它为Java程序提供了一种控制和一致性的内存访问方式。
JMM的三大特性包括
-
可见性:一个线程将自己工作内存内共享变量的最新值刷新回主内存,其他线程能收到主内存中共享变量值发生改变的通知,并能看到最新的改变。
-
原子性:一个线程在进行某个操作过程中,不可被打断,不可被分割,它要么执行成功,要么执行失败,不可处于一种中间状态。要求原子性是为了保证数据的完整性。
-
有序性:在JMM中,每个线程都按照各自独立的顺序执行,即每个线程的操作都遵循顺序执行的原则。同时,JMM通过同步机制来实现多个线程之间的有序性。
JMM的主要抽象概念是什么?
JMM的主要抽象概念包括:线程共享变量、原子性、可见性和有序性。
线程共享变量是多个线程可以访问的变量;
原子性是指操作不可分割,要么全部成功要么全部失败;
可见性是指一个线程对共享变量的修改对其他线程是立即可见的;
有序性是指程序在执行时必须遵循一些偏序关系。
JMM中的volatile关键字的作用是什么?
volatile关键字可以保证变量的可见性和有序性。
当一个变量被声明为volatile时,它可以保证多个线程之间对该变量的访问是一致的,
即每个线程都可以看到最新的值。
此外,volatile还可以保证一些指令的有序性,防止编译器进行重排。
JMM中的synchronized关键字的作用是什么?
synchronized关键字可以保证原子性和可见性。
当一个方法被声明为synchronized时,它可以保证该方法内的操作是原子的,即不会被其他线程干扰。
此外,synchronized还可以保证多个线程之间对共享变量的访问是可见的,即一个线程对共享变量的修改对其他线程是立即可见的。
JMM中的happens-before原则是什么?
happens-before原则是JMM中的一种关系规则,它定义了两个操作之间的偏序关系。
如果一个操作的结果需要对另一个操作可见,那么就称第一个操作发生在第二个操作之前(happens-before)。
JMM中规定了如果一个操作的结果需要对另一个操作可见,那么就存在一种happens-before关系。
JMM中的memory barrier是什么?
memory barrier是一种同步机制,它可以保证指令执行的顺序性和可见性。
JMM中规定了不同类型的memory barrier,包括LoadLoad、LoadStore、StoreLoad和StoreStore四种类型。
这些memory barrier可以用来保证指令执行的顺序性和可见性,从而实现正确的同步操作。
相关文章:
【面经】讲一下你对jvm和jmm的了解
JVM JVM是Java虚拟机,是Java程序的执行环境。它是一种虚拟的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现. JVM是Java程序运行的核心,可以将Java字节码转换为可执行的机器码,提供了跨平台性、优秀的垃圾回收器&…...
《网络协议》03. 传输层(TCP UDP)
title: 《网络协议》03. 传输层(TCP & UDP) date: 2022-09-04 22:37:11 updated: 2023-11-08 15:58:52 categories: 学习记录:网络协议 excerpt: 传输层、UDP、TCP(可靠传输,流量控制,拥塞控制…...
ZooKeeper调优
服务器硬件配置 建议 Zookeeper 的服务器最好专属(或是资源隔离的)。磁盘由于 Zookeeper 的数据写入磁盘,强烈建议要使用 SSD。 Linux操作系统优化 Zookeeper 的性能会很明显受到交换分区的影响。建议部署 Zookeeper 的服务器关闭交换分区功能或是通过内核参数调整,减少…...
改进YOLOv5:结合ICCV2023|动态蛇形卷积,构建不规则目标识别网络
🔥🔥🔥 提升多尺度、不规则目标检测,创新提升 🔥🔥🔥 🔥🔥🔥 捕捉图像特征和处理复杂图像特征 🔥🔥🔥 👉👉👉: 本专栏包含大量的新设计的创新想法,包含详细的代码和说明,具备有效的创新组合,可以有效应用到改进创新当中 👉👉👉: �…...
开发知识点-NodeJs-npm/Pnpm/Vite/Yarn包管理器
包管理器 vue-cli-service 不是内部或外部命令,也不是可运行的程序npm 全局变量pnpmPnpm介绍ViteYarn ‘vue-cli-service’ 不是内部或外部命令,也不是可运行的程序 yarn yarn add vue-amap yarn add vue-amap ant-design-vue npm 全局变量 换主机 新…...
Mac上好用的翻译软件推荐 兼容m
Mac翻译软件可以用在学习,工作,生活当中,一款好用的翻译软件,具有翻译准确,翻译快速等基本特点,能够帮您提高工作效率。Mac上有什么好用的翻译软件呢?今天小编为大家整理了6款好用的Mac翻译软件…...
软件下载网站
1.qt 下载官网 Index of /new_archive/qt 2.qt-vs 插件下载 Index of /official_releases/vsaddin...
java获取近期视频流关键帧与截图
1、背景 最近在做视频转发的开发时,遇到一个问题,前端订阅播放h264视频流时,有时会出现一段时间黑屏,经过测试发现是没有收到关键帧,只有第一帧是关键帧才能保证后续播放正常。所以后端需要实现一个功能,就…...
arcgis 批量删除Table中的某些Field
当shp或者table文件较少时,可以手动删除每个文件中的某些字段,当文件较多时,就需要使用arcpy或者model进行处理。...
工厂设备扫码使用售卖联网开发需要怎么开发开源代码?
我们将详细介绍如何使用开源代码开发一套用于工厂设备联网统计的系统。我们将详细讨论所需硬件组件的选择、开源框架和库的使用、软件开发流程以及最后的集成和部署。在这个过程中,我们将提供实用的操作步骤和指导,帮助你更容易地完成这个复杂的任务。 …...
软考高级之132个工具和技术
分类 工具与技术 描述 数据收集 头脑风暴 在短时间内获得大量创意,适用于团队环境,需要引导者引导(过程中可以天马行空,不要打断) 包括:头脑风暴、头脑写作 头脑写作:在开始小组创意讨论之…...
算法通过村第十八关-回溯|白银笔记|经典问题
文章目录 前言组合总和问题分割回文串子集问题排序问题字母大小写全排列单词搜索总结 前言 提示:我不愿再给你写信了。因为我终于感到,我们的全部通信知识一个大大的幻影,我们每个人知识再给自己写信。 --安德烈纪德 回溯主要解决一些暴力枚举…...
vue2 集成 - 超图 - SuperMap iClient3D for WebGL 及常用方法
文章目录 1:下载SuperMap iClient3D for WebGL2:格式化项目中所用的依赖包3:vue2 项目引入4:vue2 页面使用常见方法4.1 创建三维场景,引入在线地图资源,定位到指定位置4.2 坐标拾取4.3 用户输入事件4.4 拾取实体4.5 实体改变监听事件4.6 双击全屏4.7 相机移动事件4.8 添加…...
应用程序服务器/事件驱动编程/CommonJS介绍
目录 应用程序服务器事件驱动编程CommonJS 👍 点赞,你的认可是我创作的动力! ⭐️ 收藏,你的青睐是我努力的方向! ✏️ 评论,你的意见是我进步的财富! 应用程序服务器 应用程序服务器是一种用…...
第二十九章 目标检测中的测试模型评价指标(车道线感知)
前言 近期参与到了手写AI的车道线检测的学习中去,以此系列笔记记录学习与思考的全过程。车道线检测系列会持续更新,力求完整精炼,引人启示。所需前期知识,可以结合手写AI进行系统的学习。 介绍 自动驾驶的一大前提是保证人的安全…...
OceanBase 如何通过日志观测冻结转储流程?
本文旨在通过日志解析 OceanBase 的冻结转储流程,以其冻结检查线程为切入点,以租户(1002)的线程名为例。 作者:陈慧明,爱可生测试工程师,主要参与 DMP 和 DBLE 自动化测试项目。 爱可生开源社区…...
深度图(Depth Map)
文章目录 深度图深度图是什么深度图的获取方式激光雷达或结构光等传感器的方法激光雷达RGB-D相机 双目或多目相机的视差信息计算深度采用深度学习模型估计深度 深度图的应用场景扩展阅读 深度图 深度图是什么 深度图(depth map)是一种灰度图像…...
Ubuntu下Anaconda安装
Ubuntu下Anaconda安装 进入anaconda官网 https://www.anaconda.com/ 下载Linux64位版本; 将下载好的".sh"文件放入虚拟机中; 运行指令sudo bash Anaconda3-2023.09-0-Linux-x86_64.sh 此后会自动加载安装程序,中途会停止两次&am…...
目标检测回归损失函数(看情况补...)
文章目录 L1 loss-平均绝对误差(Mean Absolute Error——MAE)L2 loss-均方误差(Mean Square Error——MSE)Smooth L1 LossMAE、MSE、Smooth L1对比IoU LossGIoU LossDIoU Loss、CIoU LossE-IoU Loss、Focal E-IoU LossReferenceL1 loss-平均绝对误差(Mean Absolute Error——…...
将 Figma 轻松转换为 Sketch 的免费方法
最近浏览网站的时候,发现很多人不知道Figma是怎么转Sketch的。众所周知,Figma支持Sketch文件的导入,但不支持Sketch的导出,那么Figma是如何转Sketch的呢?不用担心,建议使用神器即时设计。它是一个可以实现在…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
