当前位置: 首页 > news >正文

【Java面试】二十、JVM篇(上):JVM结构

文章目录

  • 1、JVM
  • 2、程序计数器
  • 3、堆
  • 4、栈
    • 4.1 垃圾回收是否涉及栈内存
    • 4.2 栈内存分配越大越好吗
    • 4.3 方法内的局部变量是否线程安全吗
    • 4.4 栈内存溢出的情况
    • 4.5 堆和栈的区别是什么
  • 5、方法区
    • 5.1 常量池
    • 5.2 运行时常量池
  • 6、直接内存

1、JVM

Java源码编译成class字节码后,JVM负责class字节码的处理。不同操作系统下的JVM,将字节码处理成对应操作系统下的二进制文件,从而实现一次编译,到处运行。能到处运行,是因为不同操作系统有不同的JVM,也即编译后的class字节码和操作系统之间,隔着一个JVM在干活儿。

简单的理解,JVM就是Java二进制字节码的运行环境,是JDK包下包含的一些代码,像一个虚拟的计算机一样处理着class字节码。
在这里插入图片描述

JVM有两个最大的亮点:

  • 处理class字节码,实现一次编译,到处运行
  • 自动内存管理,垃圾回收机制,创建的对象,用完后不用手动回收

JVM的组成:

在这里插入图片描述

2、程序计数器

线程私有的,每个线程各有一份,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。

在这里插入图片描述

如上,线程1 执行字节码从第0行到第10行后,CPU时间片用完,线程1的程序计数器记录下当前行号。CPU的时间片分给了线程2 ,线程2执行到第9行后,CPU时间片用完。线程1再次抢到时间片,继续执行,此时,根据线程1的程序计数器,CPU就知道该从第10行继续往下执行。

3、堆

  • 堆区,线程共享
  • 保存着创建出来的对象
  • use、total、max,use == max 后,无法再分配空间,堆内存溢出

堆中有年轻代和老年代。年轻代有三部分,伊甸园区和两块大小相同的幸存者区。根据JVM策略,新创建的对象在伊甸园区,伊甸园区满了以后,触发Young GC,GC后或者的对象,复制到幸存者区,后面每GC一次,活着的对象年龄加一(对象头里存着年龄),对象GC年龄到达阈值(如15)后,晋升到老年代。

在这里插入图片描述

元空间里存类的信息、静态变量、常量、编译后的字节码信息(InstanceKlass对象(c++))。对JDK7和8,其位置变化:

  • JDK7及以前,方法区在堆区的永久代空间里
  • JDK8及以后,永久代被移除,用元空间代替,方法区在元空间,而元空间在操作系统的直接内存里,理论上可以一直分配

在这里插入图片描述

因为永久代/方法区或者说后来的元空间,存储的主要是一些类信息和常量,需求开发,加载的类越来越多,这个空间不可控,移除永久代,在本地内存放个元空间,可以防止OOM

4、栈

栈,即每个线程运行时需要的内存空间,保存着该线程方法调用的基本数据,先进后出,其中,每一个调用的方法用一个叫栈帧的东西存。

在这里插入图片描述

4.1 垃圾回收是否涉及栈内存

垃圾回收处理的主要是堆内存,对于栈内存,栈帧弹栈后,内存就会释放

4.2 栈内存分配越大越好吗

默认1024k,栈帧过大会导致线程数变少,机器总内存为512m,目前能活动的线程数则为512个,如果把内存改为2048k,则可活动的线程数上限在栈内存方面就会减半

4.3 方法内的局部变量是否线程安全吗

在方法的作用范围之内,是线程安全的。出了方法,被怎么使用就不一定了。如下:

在这里插入图片描述

每个线程过来,都会在自己的栈里创建一个m1方法对应的栈帧,栈帧里存着局部变量sb,因此线程安全。

对m2方法来说,局部变量sb是传过来的,那可能就有线程安全问题,如上面main线程中在操作sb,新开的一个线程也在操作sb。同理,m3方法,将局部变量sb return,后面可能被一个成员变量接收,但后面本质上也不关局部变量的事了

4.4 栈内存溢出的情况

  • 栈帧过多导致栈内存溢出,如递归调用
public static void m1() {m1();
}
  • 栈帧过大导致栈内存溢出

4.5 堆和栈的区别是什么

  • 栈内存一般会用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的
  • 堆会GC垃圾回收,而栈不会
  • 栈内存是线程私有的,而堆内存是线程共有的
  • 两者异常错误不同,但如果栈内存或者堆内存不足都会抛出异常,栈空间不足:Java.ang.StackOverFlowError,堆空间不足:java.lang.OutOfMemoryError.

5、方法区

  • 方法区和堆一样,各个线程共享
  • 主要存储类的信息(InstanceKclass对象)、运行时常量池
  • 虚拟机启动的时候创建,虚拟机关闭的时候释放
  • 方法区的内存空间不够时,抛异常OutOfMemoryError:Metaspace
  • 方法区是一个概念,不同版本的JDK有不同的实现,对JDK7来说,永久代是其对方法区的落地实现(且此时永久代在堆区),对JDK8来说,则给方法区换了一种实现:元空间(元空间在本地内存)

在这里插入图片描述

5.1 常量池

javap查看一个类是字节码的结构信息:可以看到类的基本信息、常量池、方法的定义:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常量池可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息

在这里插入图片描述

5.2 运行时常量池

上面提到,常量池是class文件中的,当这个类被加载,它的常量池信息就会放入到运行时常量池,并发里面的符号地址变为真实地址

在这里插入图片描述

常量池和运行时常量池的区别:

在这里插入图片描述

【区别】

6、直接内存

直接内存(操作系统分给JVM进程的内存之外的内存),不属于JVM内存,不由JVM进行管理。在进行NIO操作时,用于数据缓冲区,其分配回收成本高,但读写性能好。常规IO复制文件流程:

在这里插入图片描述

NIO复制文件流程:这块直接内存系统和Java代码都可以直接访问,少了一次缓冲区的复制操作

在这里插入图片描述

直接内存主要通过 java.nio 包下的 ByteBuffer 类来进行分配和使用。

ByteBuffer.allocateDirect(int capacity)

直接内存可以减少数据在 Java 堆和操作系统内存之间的拷贝次数,从而提高 I/O 的效率,常用于文件读写

【相关】

相关文章:

【Java面试】二十、JVM篇(上):JVM结构

文章目录 1、JVM2、程序计数器3、堆4、栈4.1 垃圾回收是否涉及栈内存4.2 栈内存分配越大越好吗4.3 方法内的局部变量是否线程安全吗4.4 栈内存溢出的情况4.5 堆和栈的区别是什么 5、方法区5.1 常量池5.2 运行时常量池 6、直接内存 1、JVM Java源码编译成class字节码后&#xf…...

【Python教程】压缩PDF文件大小

压缩 PDF 文件能有效减小文件大小并提高文件传输的效率,同时还能节省计算机存储空间。除了使用一些专业工具对PDF文件进行压缩,我们还可以通过 Python 来执行该操作,实现自动化、批量处理PDF文件。 本文将分享一个简单有效的使用 Python 压缩…...

UE4中性能优化和检测工具

UE4中性能优化和检测工具合集 简述CPUUnreal InsightUnreal ProfilerSimpleperfAndroid StudioPerfettoXCode TimeprofilerBest Practice GPUAdreno GPUMali GPUAndroid GPU Inspector (AGI) 内存堆内存分析Android StudioLoliProfilerUE5 Memory InsightsUnity Mono 内存Memre…...

大型ERP设计-业务与功能指引:外币折算与辅助账套

外币折算与辅助账套 前言:在对ORACLE和SAP的核心模块功能全面解读的基础上,给出大型ERP设计的建议-业务与功能指引,企业选型、开发大型ERP软件的公司和ERP顾问可以参考。模块包括财务、计划与制造、供应链、项目及设备(MRO),初步预…...

重学java 73.设计模式

本想送你一本沉思录,可该迷途知返的人是我 —— 24.6.18 设计模式 设计模式(Design pattern),是一套被反复使用、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、保证代码可靠性、程序的重用性,稳定性。 1995 年&#x…...

线代的学习(矩阵)

1.矩阵的乘法 矩阵实现满足:内标相等 矩阵相乘之后的结果:前行后列 需要注意:1.矩阵的乘法不具有交换律:AB!BA 2.矩阵的乘法满足分配律:A(BC) AB AC 抽象逆矩阵求逆矩阵 方法1.凑定义法、 方法2.长除法 数字型矩阵…...

【Java基础5】JDK、JRE和JVM的区别与联系

JDK、JRE和JVM的区别与联系 Java是一种广泛使用的编程语言,它的跨平台特性得益于Java虚拟机(JVM)。然而,在Java的世界里,JDK、JRE和JVM这三个术语常常让人感到困惑。本文将阐述它们各自的功能,以及它们是如…...

2024年先进机械电子、电气工程与自动化国际学术会议(ICAMEEA 2024)

2024年先进机械电子、电气工程与自动化国际学术会议(ICAMEEA 2024) 2024 International Conference on Advanced Mechatronic, Electrical Engineering and Automation 会议地点:杭州,中国 网址:www.icameea.com 邮箱: icameeasub-conf.c…...

WPF 深入理解四、样式

样式 WPF中的各类控件元素,都可以自由的设置其样式。 诸如: 字体(FontFamily) 字体大小(FontSize) 背景颜色(Background) 字体颜色(Foreground) 边距(Margin) 水平位置(HorizontalAlignment) 垂直位置(VerticalAlignment)等等。 而样式则是组织和重用以上的重要工具。不是使…...

TCP相关细节

1. 常用TCP参数 1.1 ReceiveBufferSize ReceiveBuffersize指定了操作系统读缓冲区的大小, 默认值是8192(如图5-10 所示)。在第4章的例子中,会有"假设操作系统缓冲区的长度是8" 这样的描述,可通过socket.ReceiveBufferSize 8 实现。当接收端缓冲区满了的时…...

flutter实现UDP发送魔法包唤醒主机

魔法包 魔法包是用16进制表示的数据包,它是由固定的前缀数据(FFFFFFFFFFFF)以及固定重复次数(16次)的目标主机MAC地址组成。 假设目标主机的MAC地址是:"50:eb:f6:27:ae:a8" 那么魔法包就是[FFFFFFFFFFFF50EBF627AEA850EBF627AEA850EBF627AEA8…...

回溯算法练习题(2024/6/18)

1全排列 II 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1]]示例 2: 输入:nums [1,2,3] 输出:[[1,…...

DSP——从入门到放弃系列2——PLL锁相环(持续更新)

1、概述 锁相环(Phase Locked Loop,PLL)是处理器的时钟源,控制着C6678处理器中C66x内核、各外围设备的时钟的时钟比、对准和选通功能。 2、功能描述 上图显示了PLL和PLL控制器的逻辑实现。PLL控制器提供通过软件可配置的分频器&#xff0…...

Altair 人工智能技术助力MABE预测消费者行为,实现设备性能优化

主要看点 行业: 家电行业 挑战: 企业面临的挑战是如何利用已收集的大量数据,深入了解消费者在产品使用过程中对某些保鲜程序的影响。 Altair 解决方案: Altair采用了Altair RapidMiner人工智能平台来解决问题,特别是…...

解决Spring Boot项目中数据源URL属性的问题

今天测试Springboot项目的时候,报错: . ____ _ __ _ _/\\ / ____ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | _ | _| | _ \/ _ | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) ) |____| .__|_| |_|_| |_\__, | / / / /|_||___…...

Java每日作业day6.18

ok了家人们今天我们继续学习方法的更多使用,闲话少叙,我们来看今天学了什么 1.重载 在同一个类中,可不可以存在同名的方法?重载:在同一个类中,定义了多个同名的方法,但每个方法具有不同的参数类型或参数个…...

mac如何检测硬盘损坏 常用mac硬盘检测坏道工具推荐

mac有时候也出现一些问题,比如硬盘损坏。硬盘损坏会导致数据丢失、系统崩溃、性能下降等严重的后果,所以及时检测和修复硬盘损坏是非常必要的。那么,mac如何检测硬盘损坏呢?有哪些常用的mac硬盘检测坏道工具呢? 一、m…...

怎么通俗理解概率论中的c r(cramer rao 克拉默拉奥)不等式?

还是推一下比较好记 视频链接 【数理统计学重要定理证明:C-R不等式——无偏估计的方差下界-哔哩哔哩】 https://b23.tv/4gk1AvU 【数理统计学重要定理证明:C-R不等式——无偏估计的方差下界-哔哩哔哩】...

Flask之模板

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、模板的基本用法 1.1、创建模板 1.2、模板语法 1.3、渲染模板 二、模板辅助工具 2.1、上下文 2.2、全局对象 2.3、过滤器 2.4、测试…...

如何优化 Bash 脚本的执行效率?

要优化 Bash 脚本的执行效率,可以考虑以下几个方面: 减少命令执行次数:Bash 脚本中的命令执行是比较耗时的,在可能的情况下,可以尽量减少命令的执行次数。例如,可以将多个命令合并成一个,使用管…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

大话软工笔记—需求分析概述

需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

基础测试工具使用经验

背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

Robots.txt 文件

什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...