JVM面试题(一)

news2024/11/13 18:50:01

JVM内存分哪几个区,每个区的作用是什么?

在这里插入图片描述
java虚拟机主要分为以下几个区:
JVM中方法区和堆空间是线程共享的,而虚拟机栈、本地方法栈、程序计数器是线程独享的。
(1)方法区:
a. 有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生GC,在这里进行的GC主要是对方法区里的常量池和对类型的卸载
b. 方法区主要用来存储已被虚拟机加载的类的信息、常量、静态变量和即时编译器编译后的代码等数据。
c. 该区域是被线程共享的。
d. 方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用。该常量池具有动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也会存在这个常量池中。
(2)虚拟机栈:
a. 虚拟机栈也就是我们平常所称的栈内存,它为java方法服务,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接和方法出口等信息。
b. 虚拟机栈是线程私有的,它的生命周期与线程相同。
c. 局部变量表里存储的是基本数据类型、returnAddress类型(指向一条字节码指令的地址)和对象引用,这个对象引用有可能是指向对象起始地址的一个指针,也有可能是代表对象的句柄或者与对象相关联的位置。局部变量所需的内存空间在编译器间确定
d. 操作数栈的作用主要用来存储运算结果以及运算的操作数,它不同于局部变量表通过索引来访问,而是压栈和出栈的方式
e. 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接.动态链接就是将常量池中的符号引用在运行期转化为直接引用。
(3)本地方法栈:
本地方法栈和虚拟机栈类似,只不过本地方法栈为Native方法服务。
(4)堆:
java堆是所有线程所共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例都在这里创建,因此该区域经常发生垃圾回收操作。
(5)程序计数器:
内存空间小,字节码解释器工作时通过改变这个计数值可以选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理和线程恢复等功能都需要依赖这个计数器完成。该内存区域是唯一一个java虚拟机规范没有规定任何OOM情况的区域。

heap 和stack 有什么区别

(1)申请方式
stack:由系统自动分配。例如,声明在函数中一个局部变量 int b; 系统自动在栈中为 b 开辟空间
heap:需要程序员自己申请,并指明大小,在 c 中 malloc 函数,对于Java 需要手动 new Object()的形式开辟
(2)申请后系统的响应
stack:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
heap:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
(3)申请大小的限制
stack:栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS 下,栈的大小是 2M(也有的说是 1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示 overflow。因此,能从栈获得的空间较小。
heap:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的, 自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见, 堆获得的空间比较灵活,也比较大。
(4)申请效率的比较
stack:由系统自动分配,速度较快。但程序员是无法控制的。
heap:由 new 分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
(5)heap和stack中的存储内容
stack:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址, 然后是函数的各个参数,在大多数的 C 编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
heap:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

java类加载过程?

Java类加载需要经历一下几个过程:
(1)加载
加载时类加载的第一个过程,在这个阶段,将完成一下三件事情:
a. 通过一个类的全限定名获取该类的二进制流。
b. 将该二进制流中的静态存储结构转化为方法去运行时数据结构。
c. 在内存中生成该类的Class对象,作为该类的数据访问入口。
(2)验证
验证的目的是为了确保Class文件的字节流中的信息不回危害到虚拟机.在该阶段主要完成以下四钟验证:
a. 文件格式验证:验证字节流是否符合Class文件的规范,如主次版本号是否在当前虚拟机范围内,常量池中的常量是否有不被支持的类型.
b. 元数据验证:对字节码描述的信息进行语义分析,如这个类是否有父类,是否集成了不被继承的类等。
c. 字节码验证:是整个验证过程中最复杂的一个阶段,通过验证数据流和控制流的分析,确定程序语义是否正确,主要针对方法体的验证。如:方法中的类型转换是否正确,跳转指令是否正确等。
d. 符号引用验证:这个动作在后面的解析过程中发生,主要是为了确保解析动作能正确执行。
e. 准备
准备阶段是为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配。准备阶段不分配类中的实例变量的内存,实例变量将会在对象实例化时随着对象一起分配在Java堆中。
(3)解析
该阶段主要完成符号引用到直接引用的转换动作。解析动作并不一定在初始化动作完成之前,也有可能在初始化之后。
(4)初始化
初始化时类加载的最后一步,前面的类加载过程,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的Java程序代码。

什么是类加载器,类加载器有哪些?

实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。
主要有一下四种类加载器:
(1)启动类加载器(Bootstrap ClassLoader)用来加载java核心类库,无法被java程序直接引用。
(2)扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
(3)系统类加载器(system class loader)也叫应用类加载器:它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。
(4)用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。

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

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

相关文章

开始梳理大学课程体系(一)--万字C语言总结上

C语言 前言第一章 初识C语言1.1 C语言的起源1.2 选择C语言的理由1.3 使用C语言的7个步骤 第二章 数据和C2.1 变量和常量2.1.1变量定义2.1.2 常量的定义 2.2 数据类型关键字 第三章 运算符、表达式和语句3.1 基本运算符3.1.1 算术运算符3.1.2 关系运算符3.1.3 逻辑运算符3.1.3 赋…

关于接口可维护性的一些建议 | 京东云技术团队

作者:D瓜哥 在做新需求开发或者相关系统的维护更新时,尤其是涉及到不同系统的接口调用时,在可维护性方面,总感觉有很多地方差强人意。一些零星思考,抛砖引玉,希望引发更多的思考和讨论。总结了大概有如下几…

TOB企业生态体系构建的核心要素有哪些?

To B市场作为一个非常庞大的领域,其复杂度和多元化水平,要远远要高于针对于消费者群体推进的市场。尤其近年来,消费互联网成为过去式,爆发式增长的时代结束,让资本、媒体的目光开始聚焦到以B2B企业所代表的产业互联网身…

人工智能与机器人|机器学习

原文链接: https://mp.weixin.qq.com/s/PB_n8woxdsWPtrmL8BbehA 机器学习下包含神经网络、深度学习等,他们之间的关系表示如图2-7所示。 图2-7 关系图 那么什么是机器学习、深度学习、他们的区别又是什么呢? 2.7.1 什么是机器学习&#x…

Unity中Camera.main和Camera.current的区别

在Unity中,Camera.main和Camera.current都是用来获取相机,那到底有什么区别呢? 一、异同及注意事项 1、相同点: Camera.main和Camera.current都是用于获取相机的属性。它们都是静态属性,可以通过Camera类访问。它们…

【Redis】Redis set类型实现点赞功能

文章目录 set 数据类型介绍不排序实现排序实现 set 数据类型介绍 Redis中的set类型是一组无序的字符串值。 set通过其独特的数据结构和丰富的命令提供了在存储和处理集合元素方面的一些非常有用的功能。下面列出了主要的set类型命令: SADD key member1 [member2]&a…

国产 API 工具天花板,用来搞项目真的不错

一、API爆炸的时代 随着最近行业的移动化、物联网化、数字化转型、微服务等多种概念的提出,对应的 API 数量已经呈现出爆炸式增长,由此带来的问题就是前后端的接口对接问题越来越来突出,我们能很难找到一个合适的技术工具提高我们的效率。由此…

irq_domain msi_domain 的 使用和关系

文章目录 如何创建一个 irq_domain如何创建一个 msi_domainirq domain 和 msi domain 的关系MSI对IRQdomain打的补丁变量结构体API初始化时的API申请IRQ时的API 实例 GICV3-ITS & GICV3-ITS-PCI 相关结构体变量所在文件 如何创建一个 irq_domain 内核文档说,我们可以调用如…

基于 FPGA 的彩色图像灰度化的设计实现

文章目录 前言一、系统整体设计二、各模块的功能三、彩色图像灰度化处理模块的设计1.基本原理2.彩色图像灰度化处理方法介绍方法 1:分量法方法 2:最大值法方法 3:平均值法平均值法的实现方法 4 加权平均法加权平均法的实现rgb2gray 模块rgb2g…

LeetCode965. 单值二叉树,100. 相同的树

965. 单值二叉树,100. 相同的树 965描述示例解题思路以及代码 100描述示例解题思路以及代码 965 描述 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时,才返回 true;否则返回 fals…

获得GitHub Copilot并结合VS Code使用

一、什么是GitHub Copilot GitHub Copilot是一种基于AI的代码生成工具。它使用OpenAI的GPT(生成式预训练Transformer)技术来提供建议。它可以根据您正在编写的代码上下文建议代码片段甚至整个函数。 要使用GitHub Copilot,您需要在编辑器中…

(四)Photon Voice2 的使用

一、入门 1.Voice简介 Photon Voice 2 是一个 SDK,可以轻松地向 Unity 应用程序添加高质量的低延迟语音聊天。它建立在 Photon Realtime 之上,并继承了它的所有功能,包括配对和兴趣小组。客户端加入房间并创建传出流(本地语音&a…

双目、结构光、tof,三种深度相机的原理区别看这一篇就够了!

编辑:OAK中国 首发:oakchina.cn 喜欢的话,请多多👍⭐️✍ 内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。 ▌前言 Hello,大家好,这里是OAK中国,我是助手…

win10屏幕录像哪个好用?这2款录屏软件值得推荐!

案例:win10电脑如何录屏? 【我使用的电脑是win10系统,我想对它进行屏幕录制。有没有小伙伴知道win10电脑如何录屏?win10录屏软件哪款比较好用?】 在如今互联网时代,屏幕录像是一项非常实用的功能&#xf…

【大数据之Hadoop】三十二、MapReduce生产经验

1 MapReduce跑的慢的原因 MapReduce程序效率的瓶颈在于两点: 1)计算机性能:CPU、内存、磁盘、网络 2)I/O操作优化 (1)数据倾斜 (2)Map运行时间太长,导致Reduce等待过久 …

高斯-约旦消元法

1,思想 该算法基于高斯消元,但是思想是把矩阵化为对角阵,从而避免回代的操作思路是一列一列处理,每次选为处理过的行中主元最大(极大避免精度损失)的行处理。把这一列除了主元这一行的元素,其余该列的其他…

c#笔记-委托

委托 委托是方法的类型。 有了类型就可以声明方法的变量,参数,字段。然后再调用他。 很多新人很困惑,为什么要把方法做成变量,不直接去调用它呢? 这是因为在目前你的认知里,代码都是你一个人写出来的。 如…

计算机图形学-GAMES101-5

一、观测变换 通过Viewing(观测)transformation,最终我们将世界坐标系中的物体投影到了一个xyz都处于【-1,1】的立方体中。那么接下来,我们该做什么? 二、光栅化(Rasterization) (1)透视投影的定义 定义透视投影的视…

〖大学生·技术人必学的职业规划白宝书 - 职业规划篇①〗- 大学生选择职业前的自我认知与剖析

历时18个月,采访 850 得到的需求。 不管你是在校大学生、研究生、还是在职的小伙伴,该专栏有你想要的职业规划、简历、面试的答案。说明:该文属于 大学生技术人职业规划白宝书 专栏,购买任意白宝书体系化专栏可加入TFS-CLUB 私域社…

linux之线程同步

1. 互斥锁 定义锁: pthread_mutex_t 初始化锁函数: int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr); 第一个参数是定义的互斥锁的地址,第二个参数是锁的属性,一般传NULL 互斥锁的属性在创建…