【JVM-1】JVM内存结构

news2024/11/18 14:28:16

目录

  • 什么是JVM
  • Java源码执行机制
    • class文件的组成部分
  • JVM跨平台原理
  • JVM的组成
      • 年轻代与老年代
      • 对象分配过程
        • GC类型
          • Full GC触发条件:
          • 对象进入老年代的触发条件
        • 对象分配过程:
      • 字符串常量池
      • 静态变量
      • 线程本地分配缓冲区(TLAB)
        • TLAB相关参数:
        • 使用TLAB的原因:
      • 堆内存常用参数
    • 方法区(Method Area)
      • 方法区与堆,如图所示:
      • 元空间相关参数:
      • 类信息
      • 运行时常量池
    • 虚拟机栈(VM Stack)
      • 栈与栈帧
      • 局部变量表
      • 操作数栈
      • 动态链接
        • 方法引用:
        • 绑定机制:
        • 栈顶缓存:
      • 方法返回地址
    • 程序计数器(Program Counter Register)
      • 程序计数器特点:
    • 本地方法栈(Native Method Stack)
      • 本地方法栈特点:
  • 附:JVM结构图

什么是JVM

  • JVM(Java虚拟机)是一种计算机软件,它是Java编程语言的运行环境。
  • JVM可以在各种操作系统上运行,它负责解释和执行Java字节码,并提供了一种使Java程序能够与特定操作系统和硬件交互的方式。
  • JVM也提供了垃圾回收功能,用于管理和释放程序中不再使用的内存。
  • JVM的设计使得Java程序具有平台无关性,即可以在不同的操作系统和硬件上运行,只需安装适当版本的JVM即可。

Java源码执行机制

  • Java源代码是不能直接被机器识别的,需要先经过编译器编译成JVM可以执行的.class字节码文件,再由解释器解释运行。
  • Java源文件(.java) – Java编译器 --> Java字节码文件 (.class) – Java解释器 --> 执行。
  • 字节码文件(.class)是平台无关的。
  • Java中字符只以一种形式存在:Unicode。字符转换发生在JVM和OS交界处(Reader/Writer)。
    在这里插入图片描述

class文件的组成部分

  • 结构信息:包括class文件格式版本号及各部分的数量与大小的信息
  • 元数据:对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池
  • 方法信息:对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息

JVM跨平台原理

在这里插入图片描述

JVM跨平台原理是基于字节码的。

  • Java源代码在编译时会被编译器转换为Java字节码(.class文件),而不是直接编译成机器码。这个字节码是一种中间代码,它可以在任何装有JVM的平台上运行。

  • 当Java程序被执行时,JVM会解释和执行这些字节码。JVM会将字节码翻译成特定平台的机器码,这个过程叫做即时编译(Just-In-Time Compilation)。即时编译器会将频繁执行的热点代码(Hotspot Code)编译成机器码,从而提高程序的执行效率。

  • 由于不同操作系统和硬件体系结构的差异,JVM需要针对不同平台提供特定的实现。这些不同平台上的JVM实现负责将字节码翻译成特定平台的机器码,并提供相应的运行时环境。

  • 这种通过将Java程序编译为字节码,在运行时使用JVM将字节码翻译为特定平台的机器码的方式,使得Java程序具有了跨平台的能力。只要有适当版本的JVM,Java程序就可以在任何支持JVM的平台上运行。

JVM的组成

在这里插入图片描述

JVM(Java Virtual Machine,Java虚拟机)是Java程序的运行环境,它具有以下几个主要的结构组成部分:

  1. 类加载器(Class Loader):负责将Java字节码文件加载到JVM中。类加载器将字节码文件加载到内存,并转换为JVM内部的数据结构,以供JVM执行。

  2. 执行引擎(Execution Engine):负责执行JVM中加载的字节码文件。执行引擎将字节码文件解释为机器码,并执行对应的指令。

  3. 内存区域(Memory Area):JVM将内存划分为不同的区域,用于存储不同类型的数据。主要包括:

    • 堆(Heap):存放Java对象实例和数组。
    • 方法区(Method Area):存放已加载的类的信息、常量池、静态变量等。
    • 栈(Stack):存放方法的调用栈帧和方法局部变量。
    • 程序计数器(Program Counter Register):保存当前线程执行的字节码指令地址。
    • 本地方法栈(Native Method Stack):执行本地方法的栈。
  4. 垃圾收集器(Garbage Collector):负责自动回收不再使用的内存。垃圾收集器会识别并释放不再被引用的对象,以便后续的内存分配。

  5. JNI(Java Native Interface):允许Java代码调用本地代码或者本地代码调用Java代码。JNI提供了一组接口,用于在Java和本地代码之间进行交互。

这些组成部分共同构成了JVM的结构,使得Java程序可以跨平台运行,并且具有自动内存管理等特性。

  • JVM堆(Heap)是Java虚拟机中的一块内存区域(所有线程共享),主要用于存储对象实例和数组。
  • 堆被划分为三个部分:年轻代、老年代和永久代(在JDK8中取消了永久代)
  • 其中,年轻代又被划分为Eden区、Survivor区(含:S0和S1)。
    在这里插入图片描述

堆的特点:

  • 堆内存最大
  • 堆是被线程共享,
  • 堆的目的就是存放对象,几乎所有的对象实例都在此分配。当然,随着优化技术的更新,某些数据也会被放在栈上等。

因为堆占用内存空间最大,堆也是Java垃圾回收的主要区域(重点对象),因此也称作“GC堆”(Garbage Collected Heap)
在这里插入图片描述

年轻代与老年代

  • 在年轻代中,大部分对象朝生夕死,因此,年轻代的设计目标是尽可能地减少对象的存活时间,以便更快地回收内存。
  • 默认情况下,年轻代和老年代的比例为1:2,即:年轻代占整个堆空间的1/3,老年代占整个堆空间的2/3。
  • 可以通过参数-XX:NewRatio=<n>来调整年轻代和老年代的比例。
    • 其中<n>表示老年代和年轻代的比例,默认值为2。
    • 如:设置-XX:NewRatio=2,表示老年代占整个堆空间的2/3,年轻代占整个堆空间的1/3。
  • 可以通过参数-XX:SurvivorRatio=<n>来调整Eden区和Survivor区的比例大小。
    • 其中<n>表示Eden区和一个Survivor区的比例,默认值为8。
    • 如:设置-XX:SurvivorRatio=8,表示Eden区与Survivor区的比例为8:1:1。

对象分配过程

在分析对象分配过程之前,先简单说明一下GC类型

GC类型
  • Minor GC(又称Young GC):主要用于收集年轻代中的非存活对象。Minor GC在Eden区空间不足时触发。注意:Minor GC可能会引发STW(Stop The World,即暂停用户线程)。

  • Major GC:主要用于收集老年代中的非存活对象。Major GC在老年代空间不足时触发。注意:Major GC一般都会伴随一次Minor GC,Major GC的速度一般会比Minor GC慢10倍,因此,STW的时间会更长(应尽量避免Minor GC)。目前只有CMS会有单独收集老年代的行为。

  • Mixed GC(混合收集):主要用于收集年轻代以及部分老年代中的非存活对象。目前只有G1 GC会有这种行为。

  • Full GC:主要用于收集整个堆(含:年轻代和老年代)中的非存活对象,即:Major GC+Minor GC组合。

Full GC触发条件:
  • 调用System.gc()方法时,可通过参数-XX:+ DisableExplicitGC来禁止调用System.gc()。
  • 方法区空间不足时。
  • Minor GC后,存活对象的大小超过了老年代的剩余空间。
  • Minor GC时,年轻代Survivor区空间不足,判断是否允许担保失败,不允许则触发Full GC。允许并且每次晋升到老年代的对象平均大小>老年代最大可用连续内存空间,也会触发Full GC。
  • CMS GC异常且CMS运行期间预留的内存无法满足程序需要时,抛出Concurrent Mode Failure异常,将CMS退化成Serial Old并触发Full GC。
对象进入老年代的触发条件
  • 对象的年龄达到15岁时。默认的情况下,对象经过15次Minor GC后会被转移到老年代中。对象进入老年代的Minor GC次数可以通过JVM参数:-XX:MaxTenuringThreshold进行设置,默认为15次。
  • 动态年龄判断。当一批存活对象的总大小超过Survivor区内存大小的50%时,按照年龄的大小(年龄大的存活对象优先转移)将部分存活对象转移到老年代中。
  • 大对象直接进入老年代 。当需要创建一个大于年轻代剩余空间的对象(如:一个超大数组)时,该对象会被直接存放到老年代中,可以通过参数-XX:PretenureSizeThreshold(默认值是0,即:任何对象都会先在年轻代分配内存)进行设置。
  • Minor GC后的存活对象太多无法放入Survivor区时, 会将这些对象直接转移到老年代中。
对象分配过程:
  • 新生成的对象在年轻代Eden区中分配内存,当Eden空间已满时,触发Minor GC,将不再被其他对象所引用的对象进行回收,存活下来的对象被转移到Survivor0区。
  • Survivor0区满后触发Minor GC,将Survivor0区存活下来的对象转移到Survivor1区,同时,清空Survivor0区,保证总有一个Survivor区为空。
  • 经过多次Minor GC后,仍然存活的对象被转移到老年代,进入老年代的Minor GC次数可以通过参数-XX:MaxTenuringThreshold=<N>进行设置,默认为15次。
  • 当老年代已满时会触发Major GC(即:Full GC,因此执行Major GC时会先执行Minor GC)。

分代收集的原因:将对象按照存活概率进行分类,主要是为了减少扫描范围和执行GC的频率,同时,对不同区域采用不同的回收算法,提高回收效率。

年轻代中存在两块相同大小的Survivor区的原因:解决内存碎片化,即:保证分配对象(如:大对象)时有足够的连续内存空间。

字符串常量池

  • 字符串常量池是Java中的一个特殊的存储区域,用于存储字符串常量。
  • 在Java中,字符串常量是不可变的,因此可以被共享。
  • 这样可以减少内存的使用,提高程序的性能。
  • 在JDK8中,字符串常量池存储在堆中。

静态变量

  • 静态变量是指在类中定义的变量,它们的值在整个程序运行期间都不会改变。
  • 在JDK8中取消了永久代,方法区变成了一个逻辑上的区域,因此,静态变量的内存在堆中进行分配(JDK7及以前,静态变量的内存在永久代中进行分配)。
  • 它们的生命周期与类的生命周期相同。

线程本地分配缓冲区(TLAB)

  • TLAB(Thread Local Allocation Buffer)是Java虚拟机中的一个优化技术,主要用于提高对象的分配效率。
  • 每个线程都有自己的TLAB,用于分配对象。
  • 当一个线程需要分配对象时,它会先在自己的TLAB中分配,如果TLAB中的空间不足,则会向堆中申请空间。
TLAB相关参数:
  • 参数-XX:UseTLAB:设置TLAB启动或关闭,默认开启。
  • 参数-XX:TLABWasteTargetPercent:设置TLAB所占用Eden区空间的百分比。
使用TLAB的原因:
  1. 保证创建对象时线程安全。堆(Heap)是线程共享区域,在并发环境下,对象在堆中分配内存时存在线程安全问题。通过使用TLAB(无锁方式)解决多个线程同时操作同一地址带来的线程安全问题。
  2. 提高对象的内存分配效率。在堆(Heap)中创建对象非常频繁,在并发环境下,通过加载机制为对象在堆中分配内存时会影响内存分配速度。通过使用TLAB(无锁方式)提高对象的内存分配效率。

堆内存常用参数

参数描述
-Xms堆内存初始大小,单位为m、g
-Xmx(MaxHeapSize)堆内存最大允许大小,一般不要超过物理内存的80%
-XX:PerSize非堆内存初始大小,一般应用设置初始化200m、最大1024m即可
-XX:MaxPerSize非堆内存最大允许大小
-XX:NewSize(-Xns)年轻代内存初始大小
-XX:MaxNewSize(-Xmn)年轻代内存最大允许大小
-XX:SurvivorRatio=8年轻代中Eden区与Survivor区的容量比例值,默认为8,即8:1:1
-Xss虚拟机栈内存大小

方法区(Method Area)

  • 在JDK8及之前,方法区属于永久代,而在JDK8之后,永久代被移除,方法区被移到了本地内存中,即:元空间(Meta Space)。
  • 元空间逻辑上属于堆的一部分,但是为了与堆进行区分,通常又叫非堆。元空间是各个线程共享的内存区域,它主要存储两部分内容:
    • 类信息。
    • 运行时常量池。

方法区与堆,如图所示:

在这里插入图片描述

元空间相关参数:

  • MetaspaceSize :初始化元空间大小,控制发生GC阈值,默认值为20MB。
  • MaxMetaspaceSize : 限制元空间大小上限,防止异常占用过多物理内存,默认值为-1(表示无限制)。

类信息

类信息指的是加载到方法区中的Class文件信息,Class文件信息中除了有类的版本、字段、方法、接口等描述信息外, 还包含一项常量池表(又称静态常量池)信息,常量池表主要用于存放编译器生成的各种静态常量(又称字面常量或字面量)和符号引用。

  • 静态常量:指由字母、数字等构成的字符串或者数字常量。静态常量只可以右值出现,右值指的是赋值时等号右边的值,如:int a=1,a为左值,1为右值。
  • 符号引用:符号引用主要包括以下三类常量:
    • 类和接口的全限定名。
    • 字段的名称和描述符。
    • 方法的名称和描述符。

运行时常量池

运行时常量池主要用于程序运行时为常量池表中的静态变量、符号引用等静态信息分配内存地址。

虚拟机栈(VM Stack)

  • 虚拟机栈为线程私有,它描述的是Java方法执行的内存模型。
  • 每个栈由多个栈帧(Stack Frame)组成,每个方法被执行时,Java虚拟机都会同步创建一个栈帧用于存储该方法的局部变量表、操作数栈、动态链接、方法返回地址等信息。

栈与栈帧

  • 每一个方法从被调用到执行完毕的过程,对应着一个栈帧在虚拟机栈中从入栈到出栈的过程
  • 栈顶的栈帧是当前执行方法,当这个方法调用其他方法时会创建一个新的栈帧,这个新的栈帧会被放到虚拟机栈的栈顶,变为当前活动栈帧,该栈帧所有指令都完成后,会将其从栈中移除,之前的栈帧变为当前活动栈帧,前面移除栈帧的返回值变为当前活动栈帧的一个操作数。
    在这里插入图片描述
    栈帧包含局部变量表、操作数栈、动态连接、方法返回地址等。

局部变量表

  • 局部变量表是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。
  • 在将Java文件编译成Class文件时,会在方法的Code属性的max_locals数据项中确定局部变量表所需要分配的最大容量。
  • 局部变量表的容量以变量槽(Slot)为最小单位,32位虚拟机中一个Slot可以存放32位(4字节)以内的数据类型(boolean、byte、char、short、int、float、reference以及returnAddress)。
  • 对于64位长度的数据类型(long,double),虚拟机会以高位对齐方式为其分配两个连续的Slot空间(即:将long和double数据类型读写分割成为两次32位读写)。
  • 对于reference类型,虚拟机规范没有明确说明它的长度,但虚拟机一般可以从此引用中直接或者间接地查找到对象在Java堆中的起始地址索引和方法区中的对象类型数据。
  • 为了尽可能节省栈帧空间,Slot被设计成可以重用,即:当程序计数器的指令已经超出了某个变量的作用域(执行完毕),这个变量对应的Slot就可以交给其他变量使用。但是这个机制会影响到GC,如:存在一个方法占用较多的Slot,执行完该方法的作用域后没有对Slot赋值或者清空,垃圾回收器便不能及时回收该Slot的内存。
  • 系统不会为局部变量赋予初始值(实例变量和类变量都会被赋予初始值)。

操作数栈

  • 每一个独立的栈帧中除了包含局部变量表以外,还包含一个后进先出(Last-In-First-Out)的操作数栈,操作数栈主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。

  • 当一个方法开始执行时,该方法中的操作数栈为空,在方法执行过程中,会有各种字节码指令向操作数栈中写入和提取内容(即:入栈和出栈)。

  • 如:通过操作数栈来进行算术运算、通过操作数栈来进行调用方法时的参数传递等。

  • 操作数栈和局部变量表一样,在将Java文件编译成Class文件时,在方法的Code属性的max_stack数据项中确定操作数栈所需要分配的最大容量。

  • 每一个操作数栈都会拥有一个明确的栈深度用于存储数值,32位数据类型占用一个栈单位深度,64位数据类型占用两个栈单位深度。

  • 操作数栈和局部变量表在访问方式上存在着较大差异,操作数栈并不是采用访问索引的方式进行数据访问,而是通过标准的入栈和出栈操作来完成一次数据访问。

  • 如果被调用的方法存在返回值,其返回值将会被压入当前栈帧的操作数栈中,并更新PC寄存器中下一条需要执行的字节码指令。

  • 在概念模型中,栈帧之间相互独立,大多数虚拟机都会做一些优化处理,使两个栈帧的局部变量表和操作数栈之间有部分重叠,这样在进行方法调用时可以直接共用参数,而不需要进行额外的参数复制。

动态链接

  • 每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用,包含这个引用的目的是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)。
  • 在将Java文件编译成Class文件时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在Class文件的常量池中。
  • 比如:描述一个方法调用其他方法就是通过常量池中指向该方法的符号引用来表示,动态链接的作用就是将这些符号引用转换为调用方法的直接引用。
    在这里插入图片描述
方法引用:
  • 静态链接:当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译期确定,且运行期保持不变时,这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接。
  • 动态链接:如果被调用的方法在编译期无法确定,只能在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此也被称之为动态链接。
绑定机制:

绑定指的是一个字段、方法或者类在符号引用被替换为直接引用的过程,这仅仅发生一次。静态链接和动态链接对应的方法的绑定机制为:早期绑定(Early Binding)和晚期绑定(Late Binding)。

  • 早期绑定:早期绑定就是指被调用的目标方法如果在编译期可知,且运行期保持不变时,即可将这个方法与所属的类型进行绑定。由于明确了被调用的目标方法,也就可以使用静态链接的方式将符号引用转换为直接引用。
  • 晚期绑定:如果被调用的方法在编译期无法确定,只能在程序运行期根据实际的类型绑定相关的方法,这种绑定方式也就被称之为晚期绑定。
栈顶缓存:
  • 由于操作数存储在内存中,频繁的执行内存读/写操作必然会影响执行速度。
  • 为了解决这个问题,HotSpot JVM设计者们提出了栈顶缓存技术,将栈顶元素全部缓存在物理 CPU的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率。

方法返回地址

  • 存放调用该方法的PC寄存器的值。一个方法的结束,有两种方式:

    • 正常执行完成。
    • 出现未处理的异常,非正常退出。
  • 无论通过哪种方式退出,在方法退出后都返回到该方法被调用的位置。方法正常退出时,调用者的PC计数器的值作为返回地址,即调用该方法的指令的下一条指令的地址。而方法异常退出时,返回地址需要通过异常表来确定,栈帧中一般不会保存这部分信息。

  • 正常完成出口和异常完成出口的区别在于:通过异常完成出口退出的方法不会给上层调用者产生任何的返回值。

程序计数器(Program Counter Register)

  • 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
  • 在虚拟机的概念模型中,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖程序计数器来完成。
    在这里插入图片描述

程序计数器特点:

  • 每个线程都有一个独立的程序计数器,各线程之间计数器互不影响,独立存储。
  • 执行Java方法时,程序计数器的值不为空;执行Native本地方法时,程序计数器的值为空(Undefined)。
  • 程序计数器是唯一一个在Java虚拟机规范中没有规定任何内存溢出情况的区域。

本地方法栈(Native Method Stack)

  • 本地方法栈与虚拟机栈类似,不同的是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。
  • 在Java程序调用Native方法时,Native方法所需要的内存空间在本地方法栈中开辟。

本地方法栈特点:

  • 本地方法栈为线程私有。
  • 本地方法栈允许被实现成固定或者是可动态扩展的内存大小:
    • 固定内存大小,当线程请求分配的栈容量超过本地方法栈允许的最大内存大小时,Java虚拟机会抛出StackOverflowError异常。
    • 可动态扩展内存大小,当本地方法栈尝试扩展时无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,Java虚拟机会抛出OutOfMemoryError异常。
  • Native方法一般由C/C++实现,它的具体做法是先在本地方法栈中登记Native方法,然后在执行引擎中加载本地方法库并执行。

附:JVM结构图

在这里插入图片描述

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

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

相关文章

昇思25天学习打卡营第3天 | 数据集 Dataset

数据是深度学习的基础&#xff0c;高质量的数据输入将在整个深度神经网络中起到积极作用。MindSpore提供基于Pipeline的数据引擎&#xff0c;通过数据集&#xff08;Dataset&#xff09;和数据变换&#xff08;Transforms&#xff09;实现高效的数据预处理。其中Dataset是Pipel…

【M1/M2】详细说明Parallels Desktop虚拟机的安装使用

希望文章能给到你启发和灵感~ 如果觉得有帮助的话,点赞+关注+收藏支持一下博主哦~ 阅读指南 开篇说明什么是Paralles Desktop一、基础环境说明1.1 硬件环境1.2 软件环境二、安装Parallels DeskTop2.1 下载软件安装包三、Parallels 下配置Windows 11 系统3.1 Windows 11安装3…

JavaScript学习笔记(四)

22、日期 JavaScript 日期输出&#xff0c;默认情况下&#xff0c;JavaScript 将使用浏览器的时区并将日期显示为全文本字符串&#xff1a; var data new Date();输出&#xff1a;Tue Jun 25 2024 14:45:44 GMT0800 (中国标准时间) 22.1 创建 Date 对象 Date 对象由新的 Da…

一键下单“鲜”到先得!生鲜电商小程序解决方案

随着消费者生活节奏的加快&#xff0c;以及移动互联网技术的普及&#xff0c;人们对于便捷、高效、个性化的生鲜购物体验需求日益旺盛。生鲜电商小程序以其独特的优势&#xff0c;正在改变着传统生鲜零售的格局&#xff0c;越来越多的消费者选择在线上购买生鲜食品&#xff0c;…

深圳比创达EMC|EMC与EMI滤波器:在电子设备中的平衡之道

随着科技的快速发展&#xff0c;电子设备已经深入到我们生活的方方面面&#xff0c;从家用电器到工业设备&#xff0c;从通信设备到医疗仪器&#xff0c;都离不开电子技术的支持。然而&#xff0c;电子设备在带来便利的同时&#xff0c;也面临着电磁兼容&#xff08;EMC&#x…

全球最快的 JSON 文件查询工具

本文字数&#xff1a;1684&#xff1b;估计阅读时间&#xff1a;5分钟 审校&#xff1a;庄晓东&#xff08;魏庄&#xff09; 本文在公众号【ClickHouseInc】首发 介绍 在 ClickHouse&#xff0c;我们热衷于基准测试和性能优化。所以当我第一次看到 Hacker News 上那篇“查询大…

基于 JWT 进行身份验证

一、JWT 介绍 JWT 本质上就是一组字串&#xff0c;通过&#xff08;.&#xff09;切分成三个为 Base64 编码的部分&#xff1a; Header : 描述 JWT 的元数据&#xff0c;定义了生成签名的算法以及 Token 的类型。Payload : 用来存放实际需要传递的数据Signature&#xff08;签…

【系统架构师】-收官整理-已考过

目录 1、在2023年11月第一次考试 2、在2024年5月第二次考试 3、备考过程 3.1、综合知识 3.2、案例分析 3.3、论文 我是从2023年8月开始备考架构师考试&#xff0c;一边工作&#xff0c;一遍抽空学习&#xff08;并没有参加培训&#xff09;。 1、在2023年11月第一次考试…

word2016中新建页面显示出来的页面没有页眉页脚,只显示正文部分。解决办法

问题描述&#xff1a;word2016中新建页面显示出来的页面没有页眉页脚&#xff0c;只显示正文部分。设置了页边距也不管用。 如图1 图1 解决&#xff1a; 点击“视图”——“多页”——“单页”&#xff0c;即可。如图2操作 图2 结果展示&#xff1a;如图3 图3

Springboot小型仪器公司生产管理系统-计算机毕业设计源码031853

摘 要 本论文主要论述了如何使用java语言开发一个Springboot小型仪器公司生产管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述小型仪器公司生产管理系统…

SV std::randomize使用技巧与指南

通过以下例子学习&#xff1a; 其它&#xff1a; 里面夹杂&#xff1a; if(en1) { ((a>b)&&(b>c) || (e>f)&&(j>k)); } else { }

如何提高搜索点击率:五个利用ChatGPT创造吸引眼球标题的小技巧

在当今信息爆炸的时代&#xff0c;如何让自己的文章在海量信息中脱颖而出&#xff0c;是每个内容创作者都在思考的问题。尤其是当读者面对无数个搜索结果时&#xff0c;标题成为吸引他们点击的第一步。那么&#xff0c;如何才能写出吸引眼球的标题&#xff0c;从而提高搜索点击…

星戈瑞DSPE-FITC在细胞标记中的应用

细胞标记是生物医学研究中的一项基本技术&#xff0c;它允许研究者追踪和观察细胞的行为、分布以及与周围环境的相互作用。在众多的细胞标记方法中&#xff0c;DSPE-FITC因其独特的性质和应用范围而受关注。 DSPE-FITC的基本性质 DSPE-FITC是由二硬脂酰磷脂酰乙醇胺&#xff0…

【消息队列】RabbitMQ集群原理与搭建

目录 前言1、集群搭建1.1、安装RabbitMQ1.1.1、前置要求1.1.2、安装Erlang环境①创建yum库配置文件②加入配置内容③更新yum库④正式安装Erlang 1.1.3、安装RabbitMQ1.1.4、RabbitMQ基础配置1.1.5、收尾工作 1.2、克隆VMWare虚拟机1.2.1、目标1.2.2、克隆虚拟机1.2.3、给新机设…

Mybatis 到 MyBatisPlus

Mybatis 到 MyBatisPlus Mybatis MyBatis&#xff08;官网&#xff1a;https://mybatis.org/mybatis-3/zh/index.html &#xff09;是一款优秀的 持久层 &#xff08;ORM&#xff09;框架&#xff0c;用于简化JDBC的开发。是 Apache的一个开源项目iBatis&#xff0c;2010年这…

vscode关于java扩展

包含IDEA同款代码提示&#xff0c;vscode的debug&#xff0c;除了创建类要手动新建java文件以外&#xff0c;其他都还行&#xff0c;满足初学者要求。

免费插件集-illustrator插件-Ai插件-测量路径周长

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;进行测量路径周长处理。首先从下载网址下载这款插件 https://download.csdn.net/download/m0_67316550/87890501&…

【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解

最终效果 文章目录 最终效果前言存储位置信息存储更多数据存储场景信息持久化存储数据 前言 前面写过小型游戏存储功能&#xff1a; 【unity实战】制作unity数据保存和加载系统——小型游戏存储的最优解&#xff08;包含数据安全处理方案的加密解密&#xff09; 这次做一个针…

HarmonyOS应用开发学习经验

一、HarmonyOS学习官网 开发者能力认证 HarmonyOS应用开发者基础认证6月之前的学习资源官网已经关闭过期&#xff0c;大家不要慌&#xff0c;官方更新了最新资源&#xff0c;但是&#xff0c;对于之前没有学习完的学员不友好&#xff0c;存在知识断片的现象&#xff0c;建议官…

小程序中this(1)

}, onLoad: function() {}, }) 此时经过编译后模拟器的显示&#xff1a; 这里都容易理解&#xff0c;当点击了button按钮后&#xff0c;触发点击事件执行testfun函数&#xff0c;将test02设置为8&#xff0c;如图&#xff1a; 通过this.data.test028这种方式直接赋值可以吗&…