HotSpot JVM 中的应用程序/动态类数据共享

0.前言

本文的目的是详细讨论 HotSpot JVM 自 JDK 1.5 以来提供的一项功能,该功能可以减少启动时间,但如果在多个 JVM 之间共享相同的类数据共享 (CDS) 存档,则还可以减少内存占用。

1.类数据共享 (CDS)

CDS 的想法是使用特定格式将预处理的类元数据缓存在磁盘上的存档中,以便可以非常快速地加载它们(与从 JAR 文件存储和加载的类相比会快很多)。 CDS 是在 Sun JDK 1.5 中引入的,最初仅适用于 Java HotSpot 客户端 VM 和串行垃圾收集器 (GC)。 在 JDK 9 中,它被扩展为支持 C2 Just-inTime Compiler (JIT) 和其他收集器(例如 Parallel、ParallelOld 和 G1)。 从 JDK 17 开始,它支持 ZGC、G1 GC、串行 GC、并行 GC 和 Shenandoah GC。

CDS 存档仅包含大多数应用程序使用的核心库类。 这些类(从 JDK 17 开始,总共大约 1400 个)由引导类加载器加载,它们属于以下包:java.lang.、java.util.、java.io.、java.nio.、 jdk.internal.、java.security.、java.net.* 等。CDS 存档也称为默认 CDS 存档或静态基础 CDS 存档。

从 JDK 12 (JEP 341) 开始,CDS 存档是在 64 位平台上的 JDK 构建期间通过运行 -Xshare:dump 并使用 G1 GC(默认 GC)创建的。 它使用内置时间生成的默认类列表,并且根据平台位于不同的目录下。

Linux/macOS:

// default CDS archive
$JAVA_HOME/lib/server/classes.jsa

// class list
$JAVA_HOME/lib/classlist

Windows:

// default CDS archive
$JAVA_HOME\\bin\\server\\classes.jsa

// class list
$JAVA_HOME\\bin\\classlist

CDS存档分为7个区域,如下图所示:
在这里插入图片描述
说明:

  • rw – 读写元数据(例如,C++ vtables)
  • ro – 只读元数据和只读表(例如,SymbolTable、StringTable、SystemDictionary)
  • bm – 标记存档内不同区域的所有指针位置的位图
  • ao0 – 打开归档堆空间 0(例如,java 基本类型(例如,Boolean、Char、Float 等)、Klass* 对象(例如,InstanceKlass、TypeArrayKlass*、ObjArrayKlass*))
  • ao1 – 打开归档堆空间 1(可能为空)
  • ca0 – 封闭的归档堆空间 0(例如,内部字符串)
  • ca1 – 封闭的归档堆空间 1(可能为空)

为了更深入地理解(或只是出于好奇),我建议查看 OpenJDK 源代码。

除非指定 -Xshare:off,否则在大多数 JDK 发行版中默认启用 CDS。 当 JVM 启动时,存档会进行内存映射并在多个 JVM 进程之间共享(使用共享文件系统)。 然而,目前只有具有 Compressed{Opps,ClassPointers} 的 G1 GC 可以在启动时映射存档堆区域。 使用不同的 GC(例如 SerialGC)启动 JVM 最终将禁用共享 Java 堆对象。 默认情况下,不会打印此信息,因此要获取它,您必须在启动应用程序时显式指定 -Xlog:cds 选项。

$ java -Xlog:cds -XX:+UseSerialGC -cp <app jar> MyApp

[info][cds] CDS heap data is being ignored. UseG1GC, UseCompressedOops and UseCompressedClassPointers are required.

2.归档在磁盘上的占用空间

存储在 CDS 中的类比存储在 JAR 文件或 JDK 运行时映像中的类大几倍(例如 3 – 5 倍)。 例如,JDK 17 中的默认类列表包含 1399 个类,存档总共约 13,372 KB (~ 13.05MB)。

$ cat $JAVA_HOME/lib/classlist | wc -l
1399

$ ls -l --block-size=1K $JAVA_HOME/lib/server/
-r--r--r-- 1 10668 10668 13372 Dec  7 22:48 classes.jsa

3.应用程序类数据共享(AppCDS)

应用程序类数据共享 (AppCDS) 将 CDS 概念扩展到内置系统类加载器(即应用程序类加载器)和自定义类加载器。 这最初是作为商业 Oracle JDK 功能添加的,但后来成为 OpenJDK 10 (JEP 310) 的一部分。 AppCDS 也称为静态存档。

AppCDS 存档必须显式创建,过程分为三步。

步骤 1:创建 AppCDS 类列表(例如 static-cds.lst)。 可以进行多次试运行来创建此类列表。

$ java -Xshare:off -XX:DumpLoadedClassList=static-cds.lst -cp <app jar> MyApp

如果您打开类列表,您可能会注意到它还包括核心库类(它们是默认 CDS 存档的一部分)。

步骤 2:根据之前创建的类列表创建 AppCDS 存档(例如 static-cds.jsa)

$ java -Xshare:dump -XX:SharedClassListFile=static-cds.lst -XX:SharedArchiveFile=static-cds.jsa -cp <app jar> MyApp

步骤 3:启动应用程序并指定 AppCDS 存档的名称作为参数

$ java -XX:SharedArchiveFile=static-cds.jsa -cp <app jar> MyApp

4.共享基地址

默认情况下,在转储期间,存档会映射到共享基地址 0x800000000。 如果所需的地址空间不可用,地址空间布局随机化 (ASLR) 可能会导致此操作偶尔失败。 为了使 JVM 能够应对此故障,您可以考虑使用 -Xshare:auto 选项运行它,或者(如果这对您的设置有意义;例如,在基准测试期间)甚至禁用 ASLR。

无论哪种方式,在 -Xshare:dump 期间,选项 -XX:SharedBaseAddress=<new_address> 可用于覆盖默认共享基地址或 -XX:SharedBaseAddress=0 以映射到操作系统选定的地址。

将 -Xlog:cds 选项添加到之前步骤 2 中的命令(即创建 AppCDS 存档)会打印存档区域及其基地址:

$ java -Xlog:cds -Xshare:dump -XX:SharedClassListFile=static-cds.lst -XX:SharedArchiveFile=static-cds.jsa -cp <app jar> MyApp 

[info][cds] Dumping shared data to file: 
[info][cds]    static-cds.jsa
[info][cds] Shared file region (rw )  0:  8093376 bytes, addr 0x0000000800000000 file offset 0x00001000 crc 0x5b23ef23
[info][cds] Shared file region (ro )  1: 13016776 bytes, addr 0x00000008007b8000 file offset 0x007b9000 crc 0x12a5a9d7
[info][cds] Shared file region (bm )  2:   381440 bytes, addr 0x0000000000000000 file offset 0x01423000 crc 0x80f2eed3
[info][cds] Shared file region (ca0)  3:   925696 bytes, addr 0x00000007bfc00000 file offset 0x01481000 crc 0x0e32d31c
[info][cds] Shared file region (oa0)  5:   724992 bytes, addr 0x00000007bf800000 file offset 0x01563000 crc 0xc4b5b70d

5.存储临时字符串

如果您正在使用 AppCDS,那么您可能还会有兴趣了解如何使用字符串数据和符号数据增强存档 (JEP 250)。 这可能会进一步减少应用程序的启动时间,特别是在应用程序使用大量字符串的情况下。 然而,创建额外的共享配置文件(包含字符串和符号)并不简单,因此我将尝试在这里简要解释一下。

字符串数据和符号数据可以使用附加到正在运行的 JVM 进程的 jcmd 工具生成:

$ jcmd <PID> VM.stringtable -verbose
$ jcmd <PID> VM.symboltable -verbose

然后,输出必须合并到单个文件(例如 static-cds-shared-strings.cfg),其整体结构如下:

VERSION: 1.0
@SECTION: String
$ jcmd <pid> VM.stringtable -verbose
@SECTION: Symbol
$ jcmd <pid> VM.symboltable -verbose

OpenJDK 源代码中提供了一个示例(用于测试目的)(例如,如果您想查看整体结构)。 Volker Simonis 在他的演讲中详细介绍了相同的功能:HotSpot VM 中的数据共享类。

要使用附加共享配置文件(包括字符串和符号数据)创建 AppCDS 存档,您需要使用以下参数列表启动应用程序:

$ java -Xshare:dump -XX:SharedClassListFile=static-cds.lst -XX:SharedArchiveConfigFile=static-cds-shared-strings.cfg -XX:SharedArchiveFile=static-cds.jsa -cp <app jar> MyApp

这与上面的步骤 3 非常相似,但还使用了 -XX:SharedArchiveConfigFile。

6.动态类数据共享(动态CDS)

动态 CDS 进一步扩展了 AppCDS,以动态允许在 Java 进程结束时进行归档。 该存档也简称为动态存档。 此功能自版本 13 (JEP 350) 起成为 OpenJDK 的一部分

动态 CDS 无需创建类列表(即初始 AppCDS 步骤),从而简化了 AppCDS 存档创建,因此它是一个两步过程。

第 1 步:创建动态 CDS 存档

$ java -XX:ArchiveClassesAtExit=dynamic-cds.jsa -cp <app jar> MyApp

步骤 2:启动应用程序并指定动态 CDS 存档的名称作为参数

$ java -XX:SharedArchiveFile=dynamic-cds.jsa -cp <app jar> MyApp

7.基础层依赖

动态 CDS 存档(隐式)创建在静态基本 CDS 存档(例如,classes.jsa)之上作为顶层存档,并且它使用更少的磁盘空间(因为核心库类不是其中的一部分)。 使用 -Xlog:cds 选项启动应用程序会打印两个存档:

$ java -Xlog:cds -XX:SharedArchiveFile=dynamic-cds.jsa -cp <app jar> MyApp

[info][cds] trying to map $JAVA_HOME/lib/server/classes.jsa
[info][cds] Opened archive $JAVA_HOME/lib/server/classes.jsa

[info][cds] trying to map dynamic-cds.jsa
[info][cds] Opened archive dynamic-cds.jsa

动态CDS存档和静态存档之间的分层依赖关系可以说明如下:
在这里插入图片描述
在此依赖关系链中,静态存档可以是默认 CDS 存档(即,classes.jsa)或自定义 AppCDS 存档(即,静态存档)。 用作基础层存档的 AppCDS 会覆盖默认的 CDS 存档。 动态存档仅提供可在 AppCDS 存档中的类之上加载的附加类。

当您拥有所有应用程序通用的同一组库(例如框架库)时,将 AppCDS 作为基础层中的静态存档可能会很有帮助。 此外,每个应用程序的详细信息都作为顶层存档转储在动态存档中。

8.基于AppCDS存档创建动态CDS存档

要在 AppCDS 存档之上创建动态 CDS 存档(作为非默认静态 CDS),您必须使用以下命令启动 JVM:

$ java -XX:SharedArchiveFile=static-cds.jsa -XX:ArchiveClassesAtExit=dynamic-cds.jsa -cp <app jar> MyApp

这与上面的步骤 2 非常相似,但另外 -XX:SharedArchiveFile 选项用于指定 AppCDS 存档。

9.在同一命令行中链接动态 CDS 存档和 AppCDS 存档

还可以选择在同一命令行中链接 AppCDS 和动态 CDS 存档:

$ java -XX:SharedArchiveFile=static-cds.jsa:dynamic-cds.jsa -cp <app jar> MyApp

注意:Windows 上的分隔符是 ; (反斜杠分号)而不是:(冒号)

HotSpot 不支持两个以上的存档。

使用 -Xlog:cds 选项启动应用程序会打印两个存档:

$ java -Xlog:cds -XX:SharedArchiveFile=static-cds.jsa:dynamic-cds.jsa -cp <app jar> MyApp

[info][cds] trying to map static-cds.jsa
[info][cds] Opened archive static-cds.jsa.

[info][cds] trying to map dynamic-cds.jsa
[info][cds] Opened archive dynamic-cds.jsa.

10.使用 jcmd 创建应用程序/动态 CDS 存档

到目前为止,我们在前两节中已经看到,要创建 AppCDS 或动态 CDS 存档,需要增强应用程序启动脚本(使用其他 JVM 选项),并且需要多次重新启动应用程序。 在本节中,我将介绍一种使用 jcmd 工具创建静态存档和动态存档的简化方法。

首先,启动应用程序:

$ java -cp <app jar> MyApp

其次,在应用程序运行时使用 jcmd 转储档案:

$ jcmd <PID> VM.cds static_dump static-cds.jsa
$ jcmd <PID> VM.cds dynamic_dump dynamic-cds.jsa

注意:为了能够转储动态存档,与 对应的 JVM 进程需要在启动应用程序时(在第一步中)指定一个附加选项 - XX:+RecordDynamicDumpInfo。

11.不足和建议

使用与创建时不同的 JDK 版本运行 CDS 存档不起作用(即升级 JDK 版本而不重新生成存档)。 JDK 18、19(JDK-8272331、JDK-8261455)中已解决此问题。 例如,以下存档是使用 JDK 17 创建并使用 JDK 18 启动的。

$ java -Xlog:cds -XX:SharedArchiveFile=dynamic-cds.jsa -cp <app jar> MyApp

[info][cds] Opening shared archive: dynamic-cds.jsa
[info][cds] UseSharedSpaces: Cannot handle shared archive file version 11. Must be at least 12
[info][cds] Unable to use shared archive: invalid archive

CDS 存档不可跨平台重复使用(例如 Linux、Windows、macOS)。 例如,以下存档是在 Linux 上创建并在 Windows 上启动的(即使使用相同的 JDK 版本)。

$ java -Xlog:cds -XX:SharedArchiveFile=dynamic-cds.jsa -cp <app jar> MyApp

[info][cds] trying to map dynamic-cds.jsa
[info][cds] Opened archive dynamic-cds.jsa.
[info][cds] _jvm_ident expected: OpenJDK 64-Bit Server VM (17.0.2+8-86) for windows-amd64 JRE (17.0.2+8-86), built on Dec 7 2021 21:49:10 by "mach5one" with MS VC++ 16.8 / 16.9 (VS2019)
[info][cds] actual: OpenJDK 64-Bit Server VM (17.0.2+8-86) for linux-amd64 JRE (17.0.2+8-86), built on Dec 7 2021 21:41:21 by "mach5one" with gcc 10.3.0
[info][cds] UseSharedSpaces: The shared archive file was created by a different version or build of HotSpot
[info][cds] UseSharedSpaces: Unable to map shared spaces

生成存档后,在类路径或模块路径中使用修改后的 jar 时间戳运行 CDS 存档不起作用(即禁用动态存档,仅使用基础层存档)。 这意味着重新编译类并重新创建 jar(即使源 Java 类相同、相同的工件 id 和组 id)是不可能的。

$ java -Xlog:cds -XX:SharedArchiveFile=dynamic-cds.jsa -cp <app jar> MyApp

[info][cds] trying to map /usr/lib/jvm/openjdk-17.0.2/lib/server/classes.jsa
[info][cds] Opened archive /usr/lib/jvm/openjdk-17.0.2/lib/server/classes.jsa.
[info][cds] trying to map dynamic-cds.jsa
[info][cds] Opened archive dynamic-cds.jsa.
[info][cds] Reserved archive_space_rs [0x0000000800000000 - 0x0000000804400000] (71303168) bytes
[info][cds] Reserved class_space_rs   [0x0000000804400000 - 0x0000000844400000] (1073741824) bytes
[info][cds] Mapped static  region #0 at base 0x0000000800000000 top 0x0000000800457000 (ReadWrite)
[info][cds] Mapped static  region #1 at base 0x0000000800457000 top 0x0000000800bde000 (ReadOnly)
[info][cds] Mapped dynamic region #0 at base 0x0000000800bde000 top 0x00000008021aa000 (ReadWrite)
[info][cds] Mapped dynamic region #1 at base 0x00000008021aa000 top 0x0000000804130000 (ReadOnly)
[info][cds] UseSharedSpaces: A jar file is not the one used while building the shared archive file: target/my-app-0.0.1-SNAPSHOT.jar
[info][cds] Unmapping region #0 at base 0x0000000800bde000 (ReadWrite)
[info][cds] Unmapping region #1 at base 0x00000008021aa000 (ReadOnly)
[warning][cds,dynamic] Unable to use shared archive. The top archive failed to load: dynamic-cds.jsa

CDS 存档不包括 JDK 5/6 之前的类(JDK-8202556、JDK-8230413)。 例如,以下输出是在启用 -Xlog:cds 选项的情况下生成动态存档的结果。

$ java -Xlog:cds -XX:ArchiveClassesAtExit=dynamic-cds.jsa -cp <app jar> MyApp

[warning][cds] Pre JDK 6 class not supported by CDS: 49.0 jdk/internal/reflect/GeneratedConstructorAccessor30
[warning][cds] Pre JDK 6 class not supported by CDS: 49.0 org/springframework/cglib/core/internal/Function
[warning][cds] Pre JDK 6 class not supported by CDS: 49.0 net/bytebuddy/dynamic/scaffold/MethodRegistry$Compiled
[warning][cds] Pre JDK 6 class not supported by CDS: 46.0 antlr/collections/impl/ASTArray

如果指定了 --upgrade-module-path、–patch-module 或 --limit-modules 选项,则 CDS 将被禁用。

$ java -Xlog:cds -XX:SharedArchiveFile=dynamic-cds.jsa --upgrade-module-path=target/modules -cp <app jar> MyApp

[0.000s][info][cds] optimized module handling: disabled due to incompatible property: jdk.module.upgrade.path=target/modules

创建存档时使用的类路径必须与运行时使用的类路径相同(或其前缀)。 模块路径不遵循相同的限制。

应用程序/动态 CDS 不包括其他 jar 作为类路径属性引用的 jar。

动态 CDS 档案应该在更广泛地使用应用程序(涵盖应用程序中的不同业务流程)之后创建,而不是通过启动并立即停止应用程序(即延迟加载类)来创建。

JDK版本使用越新越好。 最新的 JDK 版本包括显着的 CDS 改进或错误修复,例如:

  • JDK 15 – 尝试在动态 CDS 转储期间链接所有类(即未链接)(JDK-8232081)
  • JDK 15 – 支持动态 CDS 存档中的 Lambda 代理类 (JDK-8198698)
  • JDK 15 – ZGC(生产就绪)支持 CDS(ZGC Main)
  • JDK 16 – 支持静态 CDS 存档中的 Lambda 代理类 (JDK-8247666)
  • JDK 17 – 将旧的类文件存储在静态 CDS 存档中 (JDK-8261090)

12.总结

在我看来,AppCDS 或动态 CDS 是您应该自己尝试的功能。 这是一种几乎可以免费带来好处的机制,您不必更改应用程序代码。 这些改进有多大,我无法告诉你,这取决于具体情况。

我最近在 Java 会议上提出了类似的主题(例如 CDS、AppCDS 和动态 CDS)。 您可以下载幻灯片,此外 GitHub 上还有一个简短的教程(包括一些命令行选项和我使用的应用程序)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多分辨率展开

1.,首先这个图居然给出了基和对偶基相等这个概念。我需要说明一下这个概念的来源。 1.1.,对偶基一开始是来自高等代数的线性空间&#xff0c;然后是泛函分析中的赋范线性空间的共轭空间。至于基的概念&#xff0c;赋范线性空间并没有&#xff0c;可能是因为正交需要内积来定义&…

Python基础知识(二)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》 《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 1.输入和输出函数1.1输出函数1.2输入函数 2.常见运算符2.1赋值运算符2.2比较运算符2.3逻辑运算符2.4and逻辑与2.5or逻辑或2.6not逻…

超纯水抛光树脂MB-115的使用及装填注意事项

用前须知 01.抛光树脂是由高度纯化、转型的H型阳树脂和OH型阴树脂混合而成&#xff0c;如果装填和操作得当&#xff0c;在最初的周期中即可制备出电阻率大于18.0MΩcm和TOC小于10ppb的超纯水&#xff0c;无需化学再生。 02.树脂开封后长时间暴露在空气中会吸收二氧化碳&#…

k8s日常动手实践 ~~ pod访问 pod请求 k8s api ~ 含新版带curl的busybox镜像

前言&#xff1a; 可以使用 Kubernetes API 获取集群信息。使用 Service Account&#xff08;SA&#xff09;进行身份验证&#xff0c;可以以安全的方式访问 Kubernetes API&#xff0c;而无需在 Pod 中使用明文凭据。 以下是一个使用 Service Account 访问 Kubernetes API 获…

HAWE比例多路阀驱动放大器

HAWE比例多路阀驱动放大器是一种在工程机械和工业自动化领域中广泛使用的高精度控制元件&#xff0c;它通过电气信号来控制流体的流动方向、流量及压力等参数。多路比例阀品牌技术的核心在于高性能、低成本、智能化控制、高频响、安全性以及技术创新等方面。这些技术的发展不仅…

Web前端开发之HTML_1

第一个前端程序VS Code安装VS Code 快捷键 1. 第一个前端程序 使用记事本&#xff0c;新建一个文本文档&#xff0c;重命名为Welcome.html&#xff0c;如下图&#xff1a; 用记事本打开文档&#xff0c;内容输入如下&#xff1a; <html> <head> <t…

<计算机网络自顶向下>网络层导论

在计算机网络中&#xff0c;网络层包括数据平面和控制平面&#xff0c;它们分别负责网络数据转发和网络路由控制。以下是它们之间的区别&#xff1a; 数据平面&#xff08;Data Plane&#xff09;&#xff1a; 数据平面负责实际的数据传输和转发&#xff0c;它处理网络中的数据…

IDEA本地将镜像推送到coding制品仓库

创建制品仓库 假设仓库名称为docker 在IDEA 添加Docker 注册表 IDEA必须先安装docker插件 地址 用户名和密码就是coding的登录名和密码服务器 最好本地安装docker桌面版&#xff0c;更容易操作 测试连接成功 推送镜像到coding的docker制品仓库 选中某个镜像 鼠标右键 注册表…

金蝶云星空和旺店通·企业版单据接口对接

金蝶云星空和旺店通企业版单据接口对接 接入系统&#xff1a;旺店通企业版 慧策最先以旺店通ERP切入商家核心管理痛点——订单管理&#xff0c;之后围绕电商经营管理中的核心管理诉求&#xff0c;先后布局流量获取、会员管理、仓库管理等其他重要经营模块。慧策的产品线从旺店通…

画家-qt-surce

void GraphicView::paintEvent(QPaintEvent *pe) { QPainter painter(viewport()); painter.setRenderHint(QPainter::SmoothPixmapTransform);//升级画家 painter.drawImage(rect(),musicImage); } 分析&#xff1a; 这段代码是用于绘制图形视图的部分。 1. void GraphicV…

Hbase中二级索引与Phoenix二级索引实现

1、引入 HBase本身只提供基于行键和全表扫描的查询&#xff0c;而行键索引单一&#xff0c;对于多维度的查询困难。 所以我们引进一个二级索引的概念。二级索引的本质就是建立各列值与行键之间的映射关系 。 图解&#xff1a; 2、常见实现二级索引的方案&#xff1a; HBase…

go版本1.16.5 运行项目出现undefined: math.MaxInt报错

问题描述 go版本 go1.16.5 项目引用了 包go-sqlite3 v1.14.17 github.com/mattn/go-sqlite3 v1.14.17运行报错 # github.com/mattn/go-sqlite3 D:\GoPATH\pkg\mod\github.com\mattn\go-sqlite3v1.14.17\sqlite3_opt_serialize.go:41:26: undefined: math.MaxInt原因分析&…

离散数学之一阶逻辑基本概念与等值演算思维导图+大纲笔记(期末复习,考研,学习笔记,知识点总结)

大纲笔记 基本概念 一阶逻辑命题符号化 个体词 个体常项 个体变项 个体域 个体总域 谓词 谓词常项 谓词变项 零元谓词 特性谓词 引入规则 量词 全称量词 存在量词 一阶逻辑1公式及解释 基本概念 原子公式 谓词公式 自由变元与约束变元 自由变元 换名规则 约束变元 带入规则 闭…

强制内容在一行显示

强制内容在一行显示 .one {white-space: nowrap;overflow: hidden;text-overflow: ellipsis; /* 可选&#xff0c;当内容超出一行时&#xff0c;用省略号表示 */ }效果

构建代理IP池并自动测试可用性的爬虫实现

目录 前言 一、认识代理IP 1. 隐藏真实IP地址 2. 提高爬虫效率 二、爬取代理IP 三、测试代理IP可用性 1. 发起HTTP请求 2. 超时检测 3. 循环请求 四、构建代理IP池 五、总结 前言 随着互联网的发展&#xff0c;网络爬虫在数据采集、搜索引擎、信息监控等领域发挥着…

vue2和vue3浏览器兼容性对比

一、Vue2.0不支持IE8, 因为Vue使用了IE8无法模拟的ECMAScript 5 特性,但它支持所有兼容ECMAScript 5 的浏览器。 二、Vue3.0 不支持 IE11 及以下版本。兼容ECMAScript 5的浏览器

铝基碳化硅复合材料(AlSiC)可用于制造火星车 行业发展前景较好

铝基碳化硅复合材料&#xff08;AlSiC&#xff09;可用于制造火星车 行业发展前景较好 铝基碳化硅复合材料&#xff08;AlSiC&#xff09;又称铝基碳化硅颗粒增强复合材料&#xff0c;指由铝和碳化硅复合而成的高性能材料。铝基碳化硅复合材料具有耐腐蚀、高温稳定性好、轻量化…

机器学习笔记(二)回归

一、线性回归 线性回归是一种用于预测的统计方法&#xff0c;特别适用于连续值预测。&#x1f4c8;线性回归通过最小化误差的平方和来寻找一个线性关系&#xff0c;用于预测一个变量&#xff08;因变量&#xff09;基于一个或多个其他变量&#xff08;自变量&#xff09;的值。…

02 贪吃蛇

前言 呵呵 这是不知道 在哪里看到的 别人做的一个贪吃蛇 因此 也把我 之前的 贪吃蛇 移植上来了 当然 这个不过是为了 简单的入门了解, 呵呵 然后 c版本的贪吃蛇 需要先移植成 c 版本, 然后 再根据 单片机相关 设计调整 比如 led 点阵的输出, 比如 c99 语法的一些不兼容…

Power BI数据刷新 - 网关 数据源凭据详解

众所周知&#xff0c;如果在Power BI云服务中设置数据源自动刷新&#xff0c;有两种方式供你选择, 分别是&#xff1a; Gateway and cloud connections&#xff08;网关和云连接&#xff09;&#xff1b;Data Source Credentials&#xff08;数据源凭据&#xff09;&#xff1…