我的面试八股(JVM篇)

news2025/1/22 23:40:34

谈一谈Java内存区域和Java内存模型的理解? / Java内存区域和Java内存模型是一个东西吗?

Java内存区域和Java内存模型不是一个东西!!!!!

Java内存区域,也就是Java运行时数据区域。是指Java虚拟机在运行时创建的一个内存区域,用于存储Java程序运行时所需要的数据结构和对象实例。Java运行时数据区包括堆、方法区、虚拟机栈、本地方法栈和程序计数器等部分。

Java内存模型,也就是JMM,定义了程序中各个变量的访问规则,在虚拟机中将变量存储到内存和从内存中取出变量这种底层细节。
在这里插入图片描述

JMM

JMM(Java Memory Model)是Java虚拟机规范中定义的一种内存模型,它描述了Java程序如何在多线程环境下访问共享内存。JMM主要是为了屏蔽各种硬件和操作系统对内存访问的差异而定义出来的内存模型。JMM定义了一个抽象的计算机内存模型,包括主内存工作内存两部分。
在这里插入图片描述

  • 主内存
    主内存是所有线程共享的内存区域,也是Java内存模型中的核心部分。主内存中保存着Java对象的实例数据、类信息、方法等。
    在多线程环境下,当一个线程修改了主内存中的共享变量时,其他线程并不会立即看到这个变量的修改。这是因为每个线程都有自己的工作内存,与主内存之间存在缓存数据不一致的问题。
  • 工作内存
    每个线程都有自己的工作内存(Thread Local Memory),它是线程私有的内存区域。工作内存中保存着该线程使用到的共享变量的副本拷贝。
    当一个线程需要使用某个共享变量时,它会首先从主内存中读取该变量的值到自己的工作内存中,并对它进行操作。操作完成后,该线程再将变量的值写回主内存中。在这个过程中,其他线程并不能直接访问到该线程的工作内存。
  • 内存交互操作
    Java内存模型还定义了一些内存交互操作,包括lock、unlock、read和write等。这些操作可以保证多线程环境下共享变量的可见性和一致性。
    • lock和unlock:用于对共享变量进行加锁和解锁,确保同一时刻只有一个线程可以访问该变量。
    • read:用于将工作内存中的值传递到主内存中。
    • write:用于将主内存中的值传递到工作内存中。
  • 内存屏障
    Java内存模型还定义了内存屏障(Memory Barrier),用于控制内存交互操作的顺序和可见性。
    内存屏障分为四种类型:
    • LoadLoad屏障:保证load指令之前的所有load指令已经执行完毕。
    • StoreStore屏障:保证store指令之前的所有store指令已经执行完毕。
    • LoadStore屏障:保证load指令之前的所有指令都已经执行完毕,并且能够读取到最新的变量值。
    • StoreLoad屏障:保证store指令之前的所有指令都已经执行完毕,并且该指令所写入的变量值对于其他线程可见。

JMM的作用

保证多线程环境下的数据可见性、原子性和有序性。通过JMM规定的规范,我们可以确保多线程的正确性和可靠性。

synchronized、volatile、Lock等关键字和API有什么作用?

这些关键字和API是Java多线程编程中用来实现同步的机制,用于保证多线程环境下共享变量的可见性、有序性和原子性。其中synchronized关键字用于实现悲观锁机制,volatile关键字用于实现轻量级同步机制,Lock接口用于实现更加灵活的锁机制。

Java内存区域

1.8之前

在这里插入图片描述

1.8及之后

在这里插入图片描述
在这里插入图片描述

字符串常量池?

字符串常量池 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。

HotSpot 虚拟机中字符串常量池的实现是 src/hotspot/share/classfile/stringTable.cpp ,StringTable 本质上就是一个HashSet ,容量为 StringTableSize(可以通过 -XX:StringTableSize 参数来设置)。

StringTable 中保存的是字符串对象的引用,字符串对象的引用指向堆中的字符串对象。

JDK1.7 之前,字符串常量池存放在永久代。JDK1.7 字符串常量池和静态变量从永久代移动了 Java 堆中。

JDK 1.7 为什么要将字符串常量池移动到堆中?

主要是因为永久代(方法区实现)的 GC 回收效率太低,只有在整堆收集 (Full GC)的时候才会被执行 GC。Java 程序中通常会有大量的被创建的字符串等待回收,将字符串常量池放到堆中,能够更高效及时地回收字符串内存。

什么是直接内存?

直接内存是一种特殊的内存缓冲区,并不在 Java 堆或方法区中分配的,而是通过 JNI 的方式在本地内存上分配的。

直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 错误出现。

JDK1.4 中新加入的 NIO(Non-Blocking I/O,也被称为New I/O),引入了一种基于通道(Channel)与缓存区(Buffer)的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样就能在一些场景中显著提高性能,因为避免了在 Java 堆和 Native 堆之间来回复制数据。

直接内存的分配不会受到 Java 堆的限制,但是,既然是内存就会受到本机总内存大小以及处理器寻址空间的限制。

说一说HotSpot 虚拟机在 Java 堆中对象分配过程?

  • 类加载检查
    虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
  • 分配内存
    在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择哪种分配方式由 Java 堆是否规整决定,而 Java 堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。
  • 初始化零值
    内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
  • 设置对象头
    初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
  • 执行init方法
    在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从 Java 程序的视角来看,对象创建才刚开始, 方法还没有执行,所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来。

虚拟机内存分配的两种方式?

  • 指针碰撞

    • 适用场合:堆内存规整(没有内存碎片)的情况下
    • 原理:用过的内存全部整合到一边,没有用过的内存放到另一边,中间一个分解指针,只需要想着没用过的内存方向将该指针移动对象内存大小即可。
    • 使用该分配方式的GC收集器:Serial,ParNew
  • 空闲列表

    • 适用场合:堆内存不规整的情况下
    • 原理:虚拟机会维护一个列表,该列表中会记录哪些内存块是可用的,在分配的时候,找一块儿足够大的内存块儿来划分给对象实例,最后更新列表记录
    • 使用该分配方式的 GC 收集器:CMS

选择以上两种方式中的哪一种,取决于 Java 堆内存是否规整。而 Java 堆内存是否规整,取决于 GC 收集器的算法是"标记-清除",还是"标记-整理"(也称作"标记-压缩"),值得注意的是,复制算法内存也是规整的

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

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

相关文章

Typora自定义主题分享 (Mac风、图片立体感...)

MarkDown 主题分享 文章目录MarkDown 主题分享Ligth-浅色主题主题效果展示安装方式Dark-深色主题主题效果展示安装方式关键字:Typora 、Mac、图片阴影、代码样式、表格 Ligth-浅色主题 主题效果展示 安装方式 下载 Typora 官网 Mo主题 下载地址将Mo.css样式修改为…

Docker容器部署

Docker容器1.Docker概念1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结1.2.Docker和虚拟机的区别1.3.Docker架构1.3.1.镜像和容器1.3.2.DockerHub1.3.3.Docker架构1.3.4.小结1.4.安装Docker2.Docker的基本操…

【无人机】采用最基本的自由空间路损模型并且不考虑小尺度衰落(多径多普勒)固定翼无人机轨迹规划(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

每日刷题记录(十四)

目录第一题:子集解题思路:代码实现:第二题:组合解题思路:代码实现:第三题:全排列解题思路:代码实现:第四题:全排列II解题思路:代码实现&#xff1…

2023年4月传统行业产品经理需要考NPDP吗?含金量高吗?

产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是…

Linux内存管理(七):fixmap详解

源码基于:Linux 5.4 约定: 芯片架构:ARM64 CONFIG_ARM64_VA_BITS:39 CONFIG_ARM64_PAGE_SHIFT:12 0. 前言 内核启动首先会进入汇编阶段,mmu已经启动 (也就是说,当前SOC只能使用虚拟地址访问RAM),paging_init还没有完成调用,在内核启动过程需要访问某些特定的内核模…

SQL综合查询上

目录1、查询输出“高等数学”课程成绩前三名(不考虑成绩有重复值的情况)的学生的学号,姓名,课程名,系名,成绩。题目代码2、统计各门课程的重修人数(包括grade为NULL),要求…

体验了一把ChatGPT4

不得不说ChatGPT对我的学习效率有极大的提升,它就像一位老师,不管有什么问题,都可以得到很好的答案。但是前段时间gpt3.5账号被封了,最近搞了个gpt4。市面上目前好像没啥可以白嫖的账号,基本都是免费使用几次&#xff…

C++11新特性有效总结

目录 语言可用性加强 (读现代C教程有感) nullptr constexpr if/switch 申明强化 (C17开始) 初始化参数列表 范围for迭代 两种类型推导方式 变长参数模板 SmartPointer Lambda 多线程 (并发与并行) 并发与并行的概念 C11中的并发并行 软件…

基于单片机的温室大棚环境监测系统设计

温室大棚对北方反季节蔬菜的种植具有重要意义。据了解全国各地温室大棚使用集中,但是大棚环境调控方式落后、管理落后、生产效率比较低。针对此问题本文提出了一种基于STM32单片机智能温室大棚控制系统方案,实现环境参数的自动检测,以达到智能…

C语言从入门到精通第2天(深度解析C语言数据类型及取值范围)

C语言基本数据类型及取值范围数据存储概述基本数据类型整型数的二进制表示浮点型数的二进制表示取值范围数据存储概述 C语言的变量有着不同的数据类型,每种数据类型的取值空间都是不同的,因此,不同数据类型的变量,其取值空间也不…

利用注解和反射解决代码冗余问题(改进版)

在优化代码的时候发现,传参存在着高度冗余,如果后面需要改参数,很不方便。 String pam1 "id" appKey "&sign" sign "&method" method "&access_token" token "&times…

光隔离器的工作原理及其应用

光隔离器也称为光隔离器或光耦合器,它是一种通过使用光将电信号或电压从一个电路传输到另一个电路的装置,同时它将两个电路彼此隔离。它可以通过隔离过压信号来防止高电压或快速变化的电压损坏组件。光隔离器可以承受高达10KV的输入至输出电压和高达10KV…

html+css+JavaScript+json+servlet的社区系统(手把手教学)

目录 课前导读: 一、系统前期准备 二、前端代码的编写 三、登陆页面简介 四、注册页面 五、社区列表页 六、社区详情页 七、社区发帖页 八、注销 九、访问链接 登陆页面http://175.178.20.77:8080/java106_blog_system/login.html 总结: 课前…

HTML5 <embed> 标签、HTML5 <figcaption> 标签

HTML5 <embed> 标签 实例 被嵌入的 flash 动画片&#xff1a; <embed src"helloworld.swf">尝试一下 浏览器支持 注意: 大多数现代浏览器已经弃用并取消了对浏览器插件的支持&#xff0c;所以如果您希望您的网站可以在普通用户的浏览器上运行&#xf…

【SpringCloud系列】开发环境下重写Loadbalancer实现自定义负载均衡

前言 spring-cloud-starter-netflix-ribbon已经不再更新了&#xff0c;最新版本是2.2.10.RELEASE&#xff0c;最后更新时间是2021年11月18日&#xff0c;详细信息可以看maven官方仓库&#xff1a;https://search.maven.org/artifact/org.springframework.cloud/spring-cloud-st…

【计算机图形学】裁剪算法(逐边裁剪法 Weiler-Atherton裁剪法)

一 实验目的 编写直线段、多边形裁剪算法熟悉逐边裁剪法、Weiler-Atherton裁剪法的使用 4&#xff1a;用逐边裁剪法实现多边形裁剪&#xff08;代码最上方功能区注明是否处理退化边&#xff09; 无退化实验结果如下图所示&#xff1a; 图形初始化&#xff1a;&#xff08;红色…

GaussDB工作级开发者认证—第五章GaussDB数据库操作与管理

一、数据库对象基本操作 查询数据库&#xff1a; postgres# \l --使用元命令查看数据库 postgres# select * from pg_database; --通过系统表查看数据库 表注意事项: 只有表的所有者有权限执行ALTER TABLE命令&#xff0c;系统管理员默认拥有此权限 不能修改分区表的tables…

creator-assetbundle分包

title: creator-assetbundle分包 categories: Cocos2dx tags: [creator, 分包, assetbundle] date: 2023-04-10 15:55:22 comments: false mathjax: true toc: true creator-assetbundle分包 前篇 Asset Bundle 介绍 - https://docs.cocos.com/creator/manual/zh/asset/bundle…

国家出手管人工智能AI了

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 全球都在封杀AI&#xff0c;国家也出手了&#xff0c;人工智能AI的强监管来了!这次反应速度算是很快了。国家出手&#xff0c;AI必须管。 国家网信办拟针对生成式人工智能服务出台管理办法&#…