JAVA进阶--->JVM

news2025/6/26 7:35:58

文章目录

  • JVM--java Virtual Machine
    • JVM当时学习的存在位置
    • JVM概述(什么是JVM)
      • 为什么学习JVM?
      • 虚拟机
      • JVM作用
    • JVM组成部分
    • 类加器
      • 作用
      • 类加载过程
      • 类什么时候会被加载(初始化)
      • 类加载器
      • 双亲委派机制
      • 打破双亲委派机制
    • 运行时数据区
      • 1.程序计数器
      • 2.本地方法栈
      • 3.Java虚拟机栈
      • 4.堆
      • 方法区
    • 本地方法接口
    • 执行引擎
    • 垃圾回收(GC)
      • 垃圾回收概述
      • 垃圾回收相关算法
        • **引用计数算法**(在现代的JVM中并没有被使用)
        • **可达性分析算法/根搜索算法**
        • **对象的 finalization 机制**
        • 垃圾回收阶段的算法
        • 垃圾回收器

JVM–java Virtual Machine

JVM当时学习的存在位置

JDK,JRE,JVM

JDK:JRE+java开发工具

JRE(java运行环境):JVM+java核心类库

java开发工具:编译工具,打包工具

JVM-------- \ | /

JVM概述(什么是JVM)

为什么学习JVM?

就个人而言,学习JVM是为了面试的需要

​ 学习JVM是我能更深入的理解Java这门语言,理解Java语言底层的执行过程,为后期写出优质代码做好准备。

​ 很多时候一个问题需要深入到字节码层次去分析才能得到准确的结论,而字节码就是JVM的一部分。并且以后项目上线去排查一些程序log日志中无法呈现的问题,如:内存溢出,GC太频繁导致高延迟问题(这块可以由自己后期引导)

虚拟机

​ 虚拟机就是一个虚拟的计算机,相当于一款软件,用来执行一系列虚拟的计算机指令,虚拟机分为 系统虚拟机(VMware)和程序虚拟机(JVM)

​ JVM就是Java虚拟机,是一种执行Java字节码文件的虚拟计算机(最终解释为机械执行),拥有独立的运行机制。Java虚拟机是Java技术的核心,所有的Java程序都运行在Java虚拟机的内部。

JVM作用

​ 总的来说,JVM是运行Java字节码的虚拟机,运行并管理Java源码文件所生成的Class文件

​ Java虚拟机负责装载字节码到其内部,解释/编译为对应平台上的机械码指令执行。

​ 负责将字节码加载到内存中(运行时数据区),负责存储数据,把字节码翻译成机械码,执行,垃圾回收

特点

一次编译到处运行,自动内存管理,自动垃圾回收功能

现在的 JVM 不仅可以执行 java 字节码文件,还可以执行其他语言编译后的字节码文件,是一 个跨语言平台.

JVM组成部分

1.类加器(负责加载字节码文件)

2.运行时数据区(管理并分配内存)(存储运行时数据,堆,java虚拟机栈(运行java自己的方法),方法区,程序计数器,本地方法栈)

3.执行引擎(更底层,把字节码翻译成机械码)

4.本地方法接口

5.垃圾回收

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5DeCvdYm-1677837477346)(C:\Users\qq\AppData\Roaming\Typora\typora-user-images\1675570565121.png)]

  • 程序在执行前先要把Java代码转换成字节码(class文件)文件,JVM需要把字节码通过一定方式的类加载器(ClassLoader)把文件加载到内存的运行时数据区(Runtime Data Area),而字节码文件是JVM的一套指令集规范,并不能直接由底层操作系统区执行,因此需要特定的命令解析器**执行引擎(Execution Engine)将字节码翻译成底层系统指令再交给CPU去执行,这个过程中需要调用其他语言的接口本地库接口(Native Interface)**来实现整个程序的功能。
  • 通常需要程序员调试分析的区域就是”运行时数据区“,具体一点就是”运行时数据区“里面的Heap(堆)模块。
    在这里插入图片描述

类加器

作用

字节码刚开始会在硬盘之中,需要类加载器加载到内存中。

负责从硬盘/网络中加载字节码信息到内存中(运行时数据区的方法区中)

类加载过程

加载

使用IO读取字节码文件,转换并存储,为每个类创建一个Class类的对象并存储在方法区中

链接(验证,准备,解析)

​ 验证:检查被加载的类内部结构是否正确,对字节码文件的格式进行验证,判断文件是否被污染并对基本的语法格式进行验证。如果都验证通过,就会进入准备阶段。

​ 准备:为静态的变量进行内存分配,并设置默认初始值(在初始化阶段才真正赋值自己定义的);不包含用final修饰的static常量,在编译时进行初始化。

​ public static int value = 123;value 在准备阶段后的初始值是 0,而不是 123

​ 静态常量在编译期间就初始化

​ 解析:将符号引用转为直接引用(就是将一个类的名字转为真正的地址)

​ 将字节码中的表现形式转为内存中的表现形式(内存地址)

初始化

​ 类的初始化,为类中的定义的静态变量进行赋值

​ public static int value = 123;value 在初始化阶段后值是 123.

类什么时候会被加载(初始化)

JVM规定,每个类或者接口被首次主动使用时才对其进行初始化

1.在类中运行main方法

2.创建对象

3.使用类中的静态变量,静态方法

4.反射 Class.forName(“类的地址”);

5.子类被加载

有两种情况类不会被初始化:

  • static final int b = 20; 编译期间赋值的静态常量
  • System.out.println(User.b);
  • User[] users = new User[10]; 作为数组类型

类加载器

三个系统自带的类加载器

引导类加载器,自定义类加载器(继承实现ClassLoader类)

具体的负责加载类的一些代码

引导类加载器, 用C/C++语言开发的, JVM底层的开发语言,负责加载java核心类库。与java语言无关的。

自定义类加载器

只要继承了ClassLoader类都属于自定义类加载器

  • 扩展类加载器

​ java 语言编写的,由 sun.misc.Launcher$ExtClassLoader 实现,继承ClassLoader类.

从 JDK 系统安装目录的 jre/lib/ext 子目录(扩展目录)下加载类库

  • 应用程序类加载器

    Java 语言编写的,由 sun.misc.Launcher$AppClassLoader 实现. 派生于 ClassLoader 类.

加载程序中自己开发的类

  • tomcat中自己定义类加载器继承ClassLoader类

双亲委派机制

如果一个类加载器收到了类加载请求,它并不会自己先去加载,二十把这个请求委托给父类的加载器去执行,如果父加载器还存在其父加载器,则继续向上委托,最终将到达顶层的启动类加载器,如果父类加载器可以完成类的加载任务,就成功返回,若无法完成加载任务,子加载器才会尝试自己去加载。如果都加载失败,则抛出异常ClassNotFoundException。

目的:为了先确保加载系统类

优点:安全,可以避免用户自己编写的类替换Java的核心类库,并避免类重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次

双亲委派机制,是java提供的类加载的规范,但不是强制不能改变的.

我们可以通过自定义的类加载器,改变加载方式.

打破双亲委派机制

可以通过继承ClassLoader类,重写loadClass/findClass方法,实现自定义的类加载

典型的tomcat中,加载部署在tomcat中的项目时,就使用的是自己的类加载器

运行时数据区

Java虚拟机在执行Java程序时,会把它管理的内存划分为若干不同的数据区域。这区域各有各的用途以及生命周期。

  1. 有的区域随着虚拟机的启动而一直存在。(线程共享)
  2. 有的区域则依赖用户线程的启动和结束分别创建和销毁。(线程私有)

1.程序计数器

​ 在执行指令的时候,线程会来回切换,当切回来的时候需要直到执行下一条指令的地址,程序计数器就是用来记录当前需要执行的下一条指令的地址。

  • 程序计数器是一块很小的内存空间,用来记录每个线程运行的指令的位置
  • 是线程私有的,每个线程都拥有一个程序计数器,生命周期与线程一致
  • 是运行时数据区唯一一个内存不会溢出的空间
  • 运行速度最快

2.本地方法栈

​ 如果执行native()方法,也就是本地方法(使用C、C++写的方法),其中涉及的信息就存在这。

  • 用来运行本地方法的区域
  • 是线程私有的
  • 空间大小可以调整
  • 可能出现栈溢出

3.Java虚拟机栈

​ 对应的当前线程的信息,执行对象过程中定义的变量/属性都会存储在这。

基本作用特征:

​ 栈是运行单位,管理方法的调用运行

​ 是用来运行java方法的区域

​ 是线程私有的

​ 可能出现栈溢出

运行原理:

​ 先进后出的结构

​ 最顶部的称为当前栈帧

​ 每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧

栈帧结构:

​ 一个栈帧包含:

局部变量表(存储在方法中声明的变量)

操作数栈(实际计算运行过程)

动态链接

​ void A(){

​ B();//B方法的地址

​ }

方法返回地址

程序计数器,java栈,本地栈是线程私有的

程序计数器不会出现内存溢出

java栈,本地栈可能会出现内存溢出

java栈,本地栈大小是可以调整的

4.堆

基本作用特征

​ 在字节码编译为机器代码的过程中,会产生对象,存储在堆中

​ 是存储空间,用来存储对象,是内存空间最大的一块儿区域,

​ 在jvm启动时就被创建,大小可以调整(jvm调优)

​ 本区域是存在垃圾回收的.是线程共享的区域

堆空间的分区:(堆空间的分区是为以后垃圾回收做准备)

​ 年轻代(新生区/新生代)

​ 伊甸园区(对象刚刚创建存储在此区域)

​ 幸存者1区

​ 幸存者2区

​ 老年代(老年区)

为什么要分区

​ 可以根据对象的存活的时间放在不同的区域,可以区别对待.

​ 频繁回收年轻代,较少回收老年代.

创建对象,在堆内存中分布

1.新创建的对象,都存储在伊甸园区

2.当垃圾回收时,将伊甸园中垃圾对象直接销毁,将存活的对象,移动到幸存者1区,

3.之后创建的新对象还是存储在伊甸园区,再次垃圾回收到来时,将伊甸园中的存活对象移动到幸存者2区,

同样将幸存者1区的存活对象移动到幸存者2区,每次保证一个幸存者区为空的,相互转换.

4.每次垃圾回收时,都会记录此对象经历的垃圾回收次数,当一个对象经历过15次回收,仍然存活,就会被移动到老年代

​ 垃圾回收次数,在对象头中有一个4bit的空间记录 最大值只能是15,

5.老年区回收次数较少,当内存空间不够用时,才会去回收老年代.

堆空间的配置比例

默认的新生代与老年代的比例:1:2 可以通过 -XX:NewRatio=2 进行设置

如果项目中生命周期长的对象较多,就可以把老年代设置更大

在新生代中,伊甸园和两个幸存者区比例:8:1:1

可以通过 -XX:SurvivorRatio=8 进行设置

对象垃圾回收的年龄 -XX:MaxTenuringThreshold=

分区收集思想 Minor GC、Major GC、Full GC

部分收集、整堆收集

  • 新生区收集(Minor GC/Yang GC): 只是新生区(Eden ,S0,S1)的垃圾收集 ,回收比较频繁
  • 老年区收集(Major GC/Old GC):只是对老年区的垃圾收集,回收的次数较少
  • 整堆收集(Full GC):收集整个java堆和方法区的垃圾收集,尽量避免

整堆收集出现的情况

​ System.GC();时 程序猿几乎不用

​ 老年区空间不足

​ 方法区空间不足

​ 开发期间要避免整堆收集

堆空间的参数设置

官方文档

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

字符串常量池

在jdk7之后,将字符串常量池的位置从方法区转移到了堆空间中

因为方法区的回收在整堆收集时发生,回收频率低

堆空间回收频率高

方法区

作用: 主要用来存储加载的类信息, 以及即时编译期编译后的信息, 以及运行时常量池

特点: 在jvm启动时创建,大小也是可以调整, 是线程共享,也会出现内存溢出.

方法区,堆,栈交互关系

​ 方法区存储类信息(元信息)

​ 堆中存储创建的对象

​ 栈中存储对象引用

方法区大小设置

​ -XX:MetaspaceSize 设置方法区的大小

​ windows jdk默认的大小是21MB

​ 也可以设置为-XX:MaxMetaspaceSize 的值是-1,级没有限制. 没有限制 就可以使用计算机内存

​ 可以将初始值设置较大一点,减少了FULL GC发生

方法区的内部结构

​ 类信息

​ 以及即时编译期编译后的信息

​ 以及运行时常量池(指的就是类中各个元素的编号)

方法区的垃圾回收

​ 在FULL GC时方法区发生垃圾回收.

​ 主要是回收类信息, 类信息回收条件比较苛刻,满足以下3点即可:

​ 1.在堆中,该类及其子类的对象都不存在了

​ 2.该类的类加载器不存在了

​ 3.该类的Class对象不存在了

​ 也可以认为类一旦被加载就不会被卸载了.

特点

​ 程序计数器,java栈,本地栈是线程私有的

​ 程序计数器不会出现内存溢出

​ java栈,本地栈,堆,方法区可能会出现内存溢出

​ java栈,本地栈,堆,方法区大小是可以调整的

​ 堆,方法区是线程共享的,是会出现垃圾回收的

本地方法接口

什么是本地方法接口

简单地讲,一个 Native Method 是一个Java调用非Java代码的接囗。一个 Native Method 是这样一个Java方法:该方法的实现由非Java语言实现,比如C。

​ 用native关键字修饰的方法称为一个本地方法,没有方法体

​ hashCode();

为什么用本地方法

​ Java在有些层次的任务用Java实现起来不容易

​ java语言需要外部的环境进行交互(例如需要访问内存,硬盘,其他的硬件设备),直接访问操作系统的接口即可。

​ java的JVM本身开发也是在底层使用到了C语言

执行引擎

执行引擎包含:解释器(2种)、JIT即时编译器、GC

解释器

​ 用来执行方法区/内存里面所存储的字节码指令。

JVM设计初期,仅仅为满足Java程序实现跨平台特性,因此避免采用静态编译的方式直接生成本地机器指令,从而实现了在运行时采用逐行解释字节码到机器码执行程序的方案。

JVM发展史中,共有两套解释执行器:

古老的字节码解释器:在执行时通过纯软件代码翻译字节码的执行,效率非常低下。
现在普遍使用的模板解释器:将每一条字节码和一个模板函数相关联,模板函数中直接产生这条字节码执行时的机器码,提高了解释器的性能。
JIT即时编译器

​ 如果遇到经常执行的字节码指令,只要执行过一次,后续再来执行就不需要翻译,可以直接取出对应的机器指令,性能更快,提高了执行效率。

​ 所以JIT编译器就是将字节码指令直接编译为机器指令,只会处理一些频繁/热点的字节码指令。

由于解释器在设计和实现上非常简单,且相当低效。为了解决这个问题,JVM提供了即时编译技术:即时编译可以将整个函数体编译成为机器码,有效到避免函数体被解释执行,而是重复执行时直接执行编译后的机器码即可,大大提示了执行效率。

作用: 将加载到内存中的字节码(不是直接运行的机器码), 解释/编译为不同平台的机器码.

.java —编译–>.class 在开发期间,由jdk提供的编译器(javac)进行源码编译 (前端编译)

.class(字节码)----解释/编译—> 机器码 (后端编译,在运行时,由执行引擎完成的)

解释器: 将字节码逐行解释执行, 效率低

编译器(JIT just in time 即时编译器): 将字节码编译,缓存起来,执行更高效, 不会立即使用编译器

​ 将一些频繁执行的热点代码进行编译,并缓存到方法区中,以后执行效率提高了.

程序启动后,先使用解释器立即执行,省去了编译时间

程序运行一段时间后,对热点编译缓存,提高后续执行效率

采用的解释器和编译器结合的方案.

垃圾回收(GC)

垃圾回收概述

​ java支持自动垃圾回收,有些语言不支持需要手动

​ 第一个使用自动垃圾回收的不是Java语言,

​ 概念:垃圾收集和内存的动态分配

什么内存需要回收(什么样的对象是垃圾)

​ 垃圾就是指在运行程序中没有任何引用指向的对象,这个对象就是垃圾,如果不及时清理可能会导致内存溢出

为什么要进行垃圾回收

​ 如果不进行垃圾回收,内存迟早都会被消耗完

​ 不断的分配内存空间而不进行回收,就像不停的生产生活垃圾而从来不进行打扫一样

​ 垃圾回收也可以清除内存里的记录碎片,将这些随便进行整理占用的内存移动到堆的一端,方便JVM将整理出的内存分配给新的对象(数组必须是连续空间)。

内存溢出和内存泄露

​ 内存溢出:在程序运行过程中,经过垃圾回收处理之后创建的对象还是不能存储在内存中,即内存已经全部占用,剩余内存不足以用来存储新创建的对象

​ 内存泄露:打开了使用对象的东西,但是没有关闭,导致垃圾处理时认为对象处于运行状态,不会被回收处理,IO流 close jdbc连接 close没有关闭,生命周期很长的对象,一些已经不用的对象,但是垃圾回收器不能断定为垃圾,这些对象就默默的占用内存,称为内存泄露,大量的此类对象存在,也是导致内存溢出的原因

自动内存管理

好处: 解放程序员, 对内存管理更合理,自动化.

不好的: 对程序员管理内存的能力降低了, 解决问题能力变弱了, 不能调整垃圾回收的机制

垃圾回收相关算法

标记阶段

​ 作用:判断对象是否是垃圾对象,是否有引用指向对象

​ 相关的标记算法:引用计数算法和可达性分析算法

引用计数算法(在现代的JVM中并没有被使用)

在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就 +1 ;当引用失效时,计数器值就-1 ;任何时刻计数器为 0 的对象就是不可能再被使用的。

有个计数器来记录对象的引用数量

String s1 = new String("aaa");
String s2 = s1;  //有两个引用变量指向aaa对象
s2 = null; -1
s1 = null; -1

引用计数法原理简单,判定效率也很高,但单纯的引用计数就很难解决对象之间相互循环引用的问题。

例如,存在两个对象象objA和objB,他们都有字段instance,令objA.instance=objB;objB.instance=objA。除此之外,这两个对象再无任何引用,实际上这两个对象已 经不可能再被访问,但是它们因为互相引用着对方,导致它们的引用计数都不为零,引用计数算法也就无法回收它们。

缺点:

需要维护计数器,占用空间,频繁操作需要事件开销

无法解决循环引用问题. 多个对象之间相互引用,没有其他外部引用指向他们,计数器都不为0,不能回收,产生内存泄漏.

可达性分析算法/根搜索算法

实现思路: 从一些为根对象(GCRoots)的对象出发去查找,与根据对象直接或间接连接的对象就是存活对象,不与根对象引用链连接的对象就是垃圾对象.

GC Roots 可以是哪些元素?

在虚拟机栈中被使用的.

在方法中存储的静态成员指向的对象

作为同步锁使用的 synchronized

在虚拟机内部使用的对象

对象的 finalization 机制

当一个对象被标记为垃圾后,在真正被回收之前,会调用一次Object类中finalize(). 是否还有逻辑需要进行处理.

自己不要在程序中调用finalize(),留给垃圾回收器调用.

有了finalization机制的存在,在虚拟机中把对象状态分为3种:

1.可触及的 不是垃圾,与根对象连接的

2.可复活的 判定为垃圾了,但是还没有调用finalize(),(在finalize()中对象可能会复活)

3.不可触及的: 判定为垃圾了,finalize()也被执行过了,这种就是必须被回收的对象

垃圾回收阶段的算法

标记–复制算法:

​ 将内存分为大小相等的两块,每次只是用其中的一块,当这一块内存用完了,九江当前内存中存活着的对象复制到另一块上面,然后将正在使用的内存空间中的垃圾对象清除。
在这里插入图片描述

优点: 减少内存碎片

缺点: 如果内存中多数对象存活,则需要复制的对象数量多,效率低.

适用场景: 存活对象少 新生代适合使用标记复制算法

标记-清除算法

​ 标记-清除算法分为“标记”和“清除”两个阶段:首先标记出所有需要回 收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。
在这里插入图片描述

清除不是真正的把垃圾对象清除掉,

将垃圾对象地址维护到一个空闲列表中,后面有新对象到来时,覆盖掉垃圾对象即可.

缺点:

执行效率不稳定,如果Java堆中包含大量对 象,而且其中大部分是需要被回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过 程的执行效率都随对象数量增长而降低;
回收后有碎片产生,标记、清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致当以后在程序运行过程中需要分配较大对象时无法找 到足够的连续内存而不得不提前触发另一次垃圾收集动作。

标记-压缩算法(标记-整理)

标记-整理算法:其中的标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可 回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。

)]

缺点:

  • 移动存活对象并更新 所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用 程序才能进行。

由以上三种算法可以看出:是否移动对象都存在弊端,移动的话内存回收更复杂,不移动则内存分配会更复杂。从垃圾收集的停顿时间来看,不移动对象停顿时间会更短,甚至可以不需要停顿,但是从整 个程序的吞吐量来看,移动对象会更划算。

此外就出现了另一种解决方案:

  • 可以不在内存分配和访问上增加太大额外负担,做法是让虚 拟机平时多数时间都采用标记-清除算法,暂时容忍内存碎片的存在,直到内存空间的碎片化程度已经 大到影响对象分配时,再采用标记-整理算法收集一次,以获得规整的内存空间。

垃圾回收器

垃圾回收器是垃圾回收的实际实现者,垃圾回收算法是方法论

垃圾回收器分类

  • 按照线程数量分

    单线程垃圾回收器:Serial Serial old

    多线程垃圾回收器:Parallel

  • 按照工作模式分为

    独占式:垃圾回收线程执行时,其他线程暂停

    并行式:垃圾回收线程可以和用户线程同时执行

  • 按工作的内存区间

    年轻代垃圾回收器,老年代垃圾回收器

  • 垃圾回收期性能指标

    暂停时间(在垃圾回收过程中,其他线程暂停)

    吞吐量

    回收的速度

    占用内存大小

CMS垃圾回收器

Concurrent Mark Sweep 并发标记清除

支持垃圾回收线程与用户线程并发(同时)执行

​ 初始标记:独占式的暂停用户线程

​ 并发标记:垃圾回收线程与用户线程并发(同时)执行

​ 重新标记:独占式的暂停用户线程

​ 并发清除:垃圾回收线程与用户线程并发(同时)执行 进行垃圾对象的清除

优点:可以作到并发收集

弊端:使用标记清除算法,会产生内存碎片,并发执行影响到用户线程,无法处理浮动垃圾

三色标记:

​ 由于CMS有并发执行过程,所以在标记垃圾对象时有不确定性。

​ 所以在标记时,将对象分为三种颜色(3中状态)

​ 黑色: 例如GCRoots确定是存活的对象

​ 灰色:在黑色对象中关联的对象,其中还有未扫描完的,之后还需要再次进行扫描

​ 白色:与黑色,灰色对象无关联的,垃圾收集算法不可达的对象

标记过程:

​ 1.先确立GCRoots,把GCRoots标记为黑色

​ 2.与GCRoots关联的对象标记为灰色

​ 3.再次遍历灰色,灰色变为黑色,灰色下面有关联的对象,关联的对象变为灰色

​ 4.最终保留黑色,灰色,回收白色对象

可能会出现漏标,错标问题

G1(Garbage-First)垃圾优先

​ 将堆内存各个区又分为较小的多个区域,对这些区域进行检测,对某个区域中垃圾数量大的区域优先回收。

​ 也是并发收集的

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

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

相关文章

提取游戏《Limbus Company》(边狱公司)内素材

注意事项 相关工具会传到网盘。链接如下(如果没链接那就是过期还没更新/文章没更新) BGM: 解包工具合集(不包含uestdio,assetstdio):点击此处 此文章主要是讲解如何提取游戏内的音频文件,所以默认各位会…

Spark性能优化四 内存

文章目录(一)性能优化分析内容怎么被消耗的如何预估程序会消耗多少内存呢(二) 性能优化方案1)高性能序列化类库2)持久化或者checkpoint3)JVM 垃圾回收调优4)提高并行度5)数据本地化(一)性能优化分析 一个计…

RocketMQ的基本概念与系统架构

RocketMQ安装与启动基础概念消息(Message)主题(Topic)标签(Tag)队列(Queue)消息标识(MessageId/Key)系统架构生产者 Producer消费者 Consumer名字服务器 NameServer功能介绍路由注册路由剔除路由发现客户端…

【Spark分布式内存计算框架——Structured Streaming】1. Structured Streaming 概述

前言 Apache Spark在2016年的时候启动了Structured Streaming项目,一个基于Spark SQL的全新流计算引擎Structured Streaming,让用户像编写批处理程序一样简单地编写高性能的流处理程序。 Structured Streaming并不是对Spark Streaming的简单改进&#xf…

Hypium框架使能ArkTS应用高效测试

HarmonyOS发布了声明式开发框架ArkUI,带来了极简高效的开发体验,备受广大开发者的青睐。那么,我们在开发过程中,如何确保ArkTS应用的功能和界面满足预期呢?ArkTS应用怎样高效进行专项测试?接下来&#xff0…

机器学习管道中的数据定价

机器学习管道中的数据定价 Data Pricing in Machine Learning 作者:Pipelines Zicun Cong Xuan Luo Pei Jian Feida Zhu Yong Zhang Abstract 机器学习具有破坏性。同时,机器学习只能通过多方协作,在多个步骤中取得成功,就…

Spark 性能调优

1常规性能调优 1.1常规性能调优一:最优资源配置 Spark性能调优的第一步,就是为任务分配更多的资源,在一定范围内,增加资源的分配与性能的提升是成正比的,实现了最优的资源配置后,在此基础上再考虑进行后面…

高研发投入成就产品力,蔚来财报透露重要信号

3月1日晚间,蔚来发布了2022年第四季度及全年财报。 财报显示,蔚来四季度营收160.6亿元,同比增长62.2%,连续11个季度正增长,同时全年总营收达492.7亿元,季度和年度营收均创新高。 尽管过去一年受到新冠疫情…

妇女节到了,祝福所有女神 Happy Women‘s Day!

在每年3月8日人们庆祝妇女节 Womens Day is cllebrated on March 8 every year.国际妇女节(IWD),中国内地称“三八”国际劳动妇女节或国际劳动妇女节。是在每年的3月8日为庆祝妇女在经济、政治和社会等领域作出的重要贡献和取得的…

5个商用字体网站分享

整理了5个免费、商用字体素材网站,对你有帮助记得点赞收藏。 更多设计素材免费下载: https://www.sucai999.com/?vNTYxMjky 1、FontSpace https://www.fontspace.com/ 这个网站提供了96000款免费字体,可商业用途的字体就有17000款&#xf…

RK3568-IOT核心板不同规格品牌TF卡读写速率测试

1. 测试对象HD-RK3568-IOT 底板基于HD-RK3568-CORE工业级核心板设计(双网口、双CAN、 5路串口),接口丰富,适用于工业现场应用需求,亦方便用户评估核心板及CPU的性能。适用于工业自动化控制、人机界面、中小型医疗分析器…

VMworkstation centos虚拟机配置仅主机模式

首先是仅主机模式介绍,可以略过直接看下面具体配置过程。仅主机模式用于在宿主机和虚拟机之间建立局域网,宿主机和虚拟机之间可以互相访问,原理是建立虚拟交换机和宿主机虚拟网卡(vmnet1),宿主机虚拟网卡和…

深入分析域内ntlm relay to adcs服务的利用(含wireshark抓包分析)

前言 2021年中旬,specterops发布了一项针对域证书服务(adcs)的利用白皮书,文档中提到了19种对adcs服务的利用。本篇主要是分析文中提出的ntlm relay to adcs窃取证书的攻击流程,原理和抓包分析。 相关内容 ADCS介绍 Active Directory证书…

AI for Science系列(三):赛桨PaddleScience底层核心框架技术创新详解

继上一篇典型案例及API功能介绍,本篇重点讲解飞桨核心框架为支持科学计算任务在技术上的创新工作与成果。 框架技术创新 飞桨科学计算套件赛桨PaddleScience底层技术依赖飞桨核心框架。为了有力地支撑科学计算任务高效训练与推理,飞桨核心框架在自动微…

案例13-前端对localStorage的使用分析

一:背景介绍 前端在调用后端接口获取某一个人的评论次数、获赞次数、回复次数。调用之后判断后端返回过来的值。如果返回回来的值是0的话,从缓存中获取对应的值,如果从缓存中获取的评论次数为空那么其他两个的次数也为0。 二:思路…

SqlServer Management Studio启用身份验证登录

背景 一开始安装好SqlServer Management Studio时,默认只能用本地window身份验证登录,也就是除了SqlServer的电脑,别的都访问不了这个数据库,这是很不方便的 方案 1.打开SqlServer Management Studio,先用window身份…

windows内核学习-段和页相关

段寄存器(96位)(234条消息) 03.段寄存器_015646的博客-CSDN博客代码段寄存器CS(Code Segment)存放当前正在运行的程序代码所在段的段基址,表示当前使用的指令代码可以从该段寄存器指定的存储器段中取得,相应的偏移量则由IP提供。数…

Apinto 网关 V0.11.1 版本发布,多协议互转,新增编码转换器,接入 Prometheus

Eolink 旗下 Apinto 开源网关再次更新啦~ 一起来看看是否有你期待的功能! 1、协议转换功能上线 之前发布的 Apinto v0.10.0 已经支持了多协议的基本功能,实现多协议支持的一次验证。本次最新版本可以支持 HTTP 与 gRPC、HTTP 与 Dubbo2 之间的协议转换。…

【Java】 异步调用实践

本文要点: 为什么需要异步调用CompletableFuture 基本使用RPC 异步调用HTTP 异步调用编排 CompletableFuture 提高吞吐量BIO 模型 当用户进程调用了recvfrom 这个系统调用,kernel 就开始了 IO 的第一个阶段:准备数据。对于 network io 来说…

react Context学习记录

react Context学习记录1.Context是干嘛的2.可以倒是可以实现的做法-props逐级传递3.Context1.Context是干嘛的 一种React组件间通信方式, 常用于【祖组件】与【后代组件】间通信 2.可以倒是可以实现的做法-props逐级传递 import React, { Component } from "react";…