Java虚拟机(JVM)、垃圾回收器

一、Java简介

1、Java开发及运行版本

JRE(Java Runtime Environment,运行环境)
所有的程序都要在JRE下才能够运行。包括JVM和Java核心类库和支持文件。

JDK(Java Development Kit,开发工具包)
用来编译、调试Java程序的开发工具包。包括Java工具(javac/java/jdb等)和Java基础的类库(java API )。

JVM(Java Virtual Machine,虚拟机)
JRE的一部分,是Java的核心和基础,用来加载字节码(.class)文件、管理并分配内存、执行垃圾收集。解释自己的指令集(即字节码)并映射到本地的CPU指令集和OS的系统调用。不同的操作系统会有不同的JVM映射规则,完成跨平台性。

2、Java程序的应用版本

Java SE
标准版(桌面程序、控制台开发、嵌入式环境...),Java的基础与核心,也是JavaEE和JavaME技术的基础。
javaSE包含:面向对象、多线程、IO流、javaSwing

Java EE
在javaSE的基础上,创建了规范和框架,提供Web服务、组件模型、管理和通信API、服务器开发,如开发B/S架构软件
javaEE包含:serclet、jstl、jsp、spring、mybatis

Java ME
机顶盒、移动电话和PDA之类嵌入式消费电子设备提供的Java语言平台,包括虚拟机和一系列标准化的Java API。

Java Card
支持一些java小程序(Applets),运行在小内存设备上的平台。

二、Java的类加载

1、类加载器种类

启动类加载器(Bootstrap ClassLoader)
负责加载%JAVA_HOME%/lib目录下的 jar 包和类。它只能加载自己能够识别的类。
扩展类加载器(Extendtion ClassLoader)
它负责加载<JAVA_HOME>\lib\ext目录中的或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以使用扩展类加载器。
应用程序类加载器(Application ClassLoader)
负责加载ClassPath上所指定的类库,如果应用程序没有自定义过自己的类加载器,一般情况下这就是程序的默认类加载器。
自定义类加载器(CustomerClassLoader)
自己定义的类加载器,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。

2、类加载步骤

1.加载(类加载器完成)

1.通过类的全限定名来获取定义此类的二进制字节流
2.将这个类字节流代表的静态存储结构转为方法区的运行时数据结构
3.在堆中生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口。

2.校验(连接阶段)

确保Class文件的字节流中包含的信息符合当前虚拟机的要求,不危害虚拟机的自身安全。
1.文件格式验证:基于字节流验证。
2.元数据验证:基于方法区的存储结构验证。
3.字节码验证:基于方法区的存储结构验证。
4.符号引用验证:基于方法区的存储结构验证。

3.准备(连接阶段)

为类变量分配内存,并将其初始化为默认值。在方法区中分配这些变量所使用的内存空间。
例1:
public static int value = 123;
此时在准备阶段过后的初始值为0而不是123;
例2:
public static final int value = 123;
此时value的值在准备阶段过后就是123。

4.解析(连接阶段)

把类型中的符号引用转换为直接引用,主要四种:
1.类或接口的解析
2.字段解析
3.类方法解析
4.接口方法解析

5.初始化

为类的静态变量赋予正确的初始值、执行类的静态代码块。
如果有父类,则先运行父类中的变量赋值语句和静态语句。

6.注意

1.类在使用时才会加载:反射触发、 new 对象。
2.加载类的子类会先加载父类。
3.static final修饰的常量属性会存到常量池中,类不会加载。

三、JVM的内存模型

运行时数据区域

1、程序计数器

存放下条指令所在单元的地址。

2、线程栈(虚拟机栈)

1.局部变量表:存储基本数据类型(int、float、byte等),如果是引用数据类型,则存储的是其在堆中的内存地址,也就是指向对象的一个指针。
2.操作数栈:操作数运算时一块临时的空间来存放操作数。
3.动态链接:将代码的符号引用转换为在方法区(运行时常量池)中的直接引用。
4.方法出口:存储了栈帧中的方法执完之后回到上一层方法的位置。

3、本地方法栈

与虚拟机栈结构一致,本地方法栈执行的是Java底层由C++编写的native方法。

4、元空间(方法区)

主要包括:常量、静态变量、类信息(对象头)、运行时常量池,操作的是直接内存。
默认情况下是off heap的(堆的一个逻辑分区)内存,大小不受jvm大小的限制,属于操作系统内存。
运行时常量池:虚拟机启动,将各个Class文件中的常量池载入到运行时常量池中(加载到内存中)。Class常量池只是一个媒介场所。

5、堆

虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

5.1 对象结构

四、垃圾回收

1、回收策略

1.四种引用类型

强引用
使用最普遍的引用。垃圾回收器绝对不会回收它,内存不足时宁愿抛出 OOM 导致程序异常,平常的 new 对象就是。
软引用
垃圾回收器在内存充足时不会回收软引用(SoftReference)对象,不足时会回收它,特别适合用于创建缓存。
弱引用
在扫描到该对象时无论内存是否充足都会回收该对象。ThreadLocal 的 Key 就是弱引用。
虚引用
如果一个对象只具有虚引用(PhantomReference)那么跟没有任何引用一样,任何适合都可以被回收。主要用跟踪对象跟垃圾回收器回收的活动。

2.判定堆中对象是否为垃圾

引用计数法:在对象中添加一个引用计数器,当有地方引用这个对象时,引用计数器值+1,当引用失效时,计数器值-1。两个对象循环引用的时,各自的计数器始终不会变成0,导致无法回收,引起内存泄露。(一般不采用)。
可达性分析法:从GCRoots的对象虚拟机栈、方法区的类属性引用的对象、方法区中常量引用的对象、本地方法栈中引用的对象)的引用连来判断是否为垃圾。

3.回收算法

1.标记–清除
首先通过根节点,标记所有从根节点开始的可达对象。清除阶段,清除所有未被标记的对象。
2.标记–整理(压缩)
标记-压缩算法从根节点开始,对所有可达对象做一次标记。将所有的存活对象压缩到内存的一端,清理边界外所有的空间。
3.标记-复制
将内存区域均分为了两块(记为S0和S1),创建对象的时只用其中的一块(如S0),当S0使用完之后,将S0上面存活的对象全复制到S1上去,然后将S0全部清理掉。
4.分代收集
目前大部分JVM的采用的算法。根据对象存活周期将内存划分为几块。根据每块内存区间的特点,使用不同的回收算法,以提高垃圾回收的效率。
将Java堆划分为新生代 (Young Generation)和老年代(Old Generation)两个区域。新生代又分为Eden区、From Survivor和To Survivor。

4.三色标记法

1.三色

黑色:表示根对象,或者该对象与它引用的对象都已经被扫描过了。
灰色:该对象本身已经被标记,但是它引用的对象还没有扫描完。
白色:未被扫描的对象,如果扫描完所有对象之后,最终为白色的为不可达对象,也就是垃圾对象。

2.三色标记过程

1.初始时,全部对象都是白色的
2.GC Roots直接引用的对象变为灰色
3.从灰色集合中获取元素;将本对象直接引用的对象标记为灰色;然后将当前的对象标记为黑色。
4.重复步骤3,直到灰色的对象集合全部变为空
5.结束后,仍然被标记为白色的对象就是不可达对象,就视为垃圾对象。

2、各类回收器

垃圾收集器工作方式作用空间     算法  特点适用场景
Serial
串行
新生代
复制算法
响应速度优先
适用于单CPU环境下的client模式
ParNew
并行
新生代
复制算法
响应速度优先
多CPU环境Server模式下与CMS配合使用
Parallel
并行
新生代
复制算法
吞吐量优先
适用于后台运算而不需要太多交互的场景
Serial Old
串行
老年代
标记-整理(压缩)算法
响应速度优先
适用于单CPU环境下的Client模式
Paraller Old
并行
老年代
标记-整理(压缩)算法
吞吐量优先
适用于后台运算而不需要太多交互的场景
CMS
并发
老年代
标记-清除算法
响应速度优先
适用于互联网或B/S业务
G1
并发、并行
新生代、老年代
标记-整理(压缩)算法
响应速度优先
响应速度优先

1、对象分配

1.优先分配到Eden。
2.如果对象在Eden出生并经过第一次 Minor GC后仍然存活,且能被 Survivor容纳的话,将被移动到 Survivor空间中。对象在Survivor区中每熬过一次 Minor GC,年龄就增加1岁,当到达阈值(默认为15岁,其实每个JVM、每个GC都有所不同)时,就会被晋升到老年代中。
3.大对象直接分配到老年代,尽量避免程序中出现过多的大对象。
4.长期存活的对象分配到老年代。
5.动态对象年龄判断,如果 Survivor区中相同年龄的所有对象大小的总和大于 Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无须等到MaxtenuringThreshold中要求的年龄。

2.GC收集

新生代收集(Minor GC/ Young GC):新生代的垃圾收集。
老年代收集(Major GC/ old GC):老年代的垃圾收集。目前,只有 CMS GC会有单独收集老年代的行为。注意,很多时候 Major GC会和Full GC混淆使用,需要具体分辨是老年代回收还是整堆回收。
混合收集(Mixed GC):收集整个新生代以及部分老年代的垃圾收集,目前,只有G1会有这种行为。
整堆收集(Full GC):收集整个java堆和方法区的垃圾收集。

1.年轻代GC(Minor GC)触发机制

(1)当年轻代空间不足时,就会触发 Minor GC,这里的年轻代满指的是Eden代满,,Survivor满不会引发GC。(每次 Minor Gc会清理年轻代的内存。)
(2)因为Java对象大多都具备朝生夕灭的特性,所以 Minor gc非常频繁,一般回收速度也比较快。这一定义既清晰又易于理解。
(3)Minor gc会引发STW,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行。

2.老年代GC(Major GC/FullGC)触发机制

(1)指发生在老年代的GC,对象从老年代消失时, Major GC”或“Fu11GC发生了。
(2)出现了 Major GC,经常会伴随至少一次的 Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行 Major GC的策略选择过程)。
(3)也就是在老年代空间不足时,会先尝试触发 Minor GC。如果之后空间还不足,则触发 Major GC。
(4)Major GC的速度一般会比 Minor gc慢10倍以上,STW的时间更长。

3.触发FullGc执行的情况

(1)调用 System. gc()时,系统建议执行Fu11GC,但是不必然执行。
(2)老年代空间不足。
(3)方法区空间不足。
(4)通过 Minor GC后进入老年代的平均大小大于老年代的可用内存。
(5)由Eden区、 from区向 from区复制时,对象大小大于 To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。

3、G1回收器

G1 作为 JDK9 之后的服务端默认收集器,不再区分年轻代和老年代进行垃圾回收。
G1 默认把堆内存分为 N 个分区,每个 1~32M。提供了四种不同区域标签 Eden、Survivor 、Old、 Humongous。H(Humongous)区可以认为是 Old 区中一种特列专门用来存储大数据的。

1.G1的运行过程

1.初始标记:标记下GC Roots能直接关联到的对象。这个阶段需要短暂停顿线程。
2.并发标记:从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。
3.最终标记:对用户线程做一个短暂的暂停,用于处理并发标记阶段仍遗留下来的最后那少量的SATB记录(漏标对象)。
4.筛选回收:负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,采用复制清除算法,把有用的复制到新Region,再清理掉整个旧Region的全部空间。须暂停用户线程,由多个收集器线程并行完成。

2.G1的特点

优点:
1、支持较大的内存。
2、暂停时间可控。
3、压缩空间,避免产生内存碎片。
4、简单配置就能达到很好的性能。
5、内存模型方面:G1采用物理分区,逻辑分代,不连续的内存区域Region组成。而CMS中Eden,Survivor,Old区是连续的一整块内存。
6、G1既可以收集年轻代,也可以收集老年代,而CMS只能在老年代使用。
缺点:
1、记忆集RSet会占用比较大的内存,因此不建议在小内存下使用G1,推荐至少6G。
2、对CPU的负载可能会更大一点。
3、由于采用复制算法,GC垃圾回收过程对象复制转移会占用较多的内存,更容易出现回收失败(Allocation (Evacuation) Failure)的问题。
4、可能会降低吞吐量。
虽然 G1收集器的垃圾收集暂停时间通常要短得多,但应用程序吞吐量也往往略低一些。
相当于把一次垃圾回收的工作,分开多次进行执行(主要指老年代),单次暂停的时间虽然更加可控,但是由于每次垃圾回收的空间会更少,
总体来说垃圾回收的效率会更低,暂停的总时间会更长,所以吞吐量往往会略低一些。

3.对比CMS

CMS的老年代回收采用的是标记-清除算法
初始标记:标记GC root能直接关联的对象(短暂STW)。
并发标记:GCRootsTracing,从并发标记中的root遍历,对不可达的对象进行标记。
重新标记:修正并发标记期间因为用户操作导致标记发生表更的对象,采用的incremental update算法,会出现比较多的STW。
并发清除:由于是直接清理,不涉及对象的复制转移,所以阶段可以并发执行。

五、JVM的工具及调优

1、工具

jps:输出 JVM 中运行的进程状态信息
jstack:生成虚拟机当前时刻的线程快照
jstat:虚拟机统计信息监控工具
jinfo:实时地查看和调整虚拟机各项参数
jmap:生成虚拟机的内存转储快照,heapdump 文件
JConsole:可视化管理工具,常用

2、调优

在没有全面监控、收集性能数据之前,调优是盲目的(一般项目加个 xms 和 xmx 参数就够)。
日常分析 GC 情况优化代码比优化 GC 参数要多得多。一般如下情况不用调优的:
minor GC 单次耗时 < 50ms,频率 10 秒以上。说明年轻代 OK。
Full GC 单次耗时 < 1 秒,频率 10 分钟以上,说明年老代 OK。
GC 调优目的:GC 时间够少,GC 次数够少。

3、调优建议

-Xms5m 设置 JVM 初始堆为 5M,-Xmx5m 设置 JVM 最大堆为 5M。-Xms 跟-Xmx 值一样时可以避免每次垃圾回收完成后 JVM 重新分配内存。
-Xmn2g:设置年轻代大小为 2G,一般默认为整个堆区的 1/3 ~ 1/4。- Xss 每个线程栈空间设置。
-XX:SurvivorRatio,设置年轻代中 Eden 区与 Survivor 区的比值,默认=8,比值为 8:1:1。
-XX:+HeapDumpOnOutOfMemoryError 当 JVM 发生 OOM 时,自动生成 DUMP 文件。
-XX:PretenureSizeThreshold 当创建的对象超过指定大小时,直接把对象分配在老年代。
-XX:MaxTenuringThreshold 设定对象在 Survivor 区最大年龄阈值,超过阈值转移到老年代,默认 15。
开启 GC 日志对性能影响很小且能帮助我们定位问题,-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:gc.log

4、JVM 参数 

参数        说明                实例
-Xms    初始堆大小,默认物理内存的1/64    -Xms512M
-Xmx    最大堆大小,默认物理内存的1/4    -Xms2G
-Xmn    新生代内存大小,官方推荐为整个堆的3/8    -Xmn512M
-Xss    线程堆栈大小,jdk1.5及之后默认1M,之前默认256k    -Xss512k
-XX:NewRatio=n    设置新生代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4    -XX:NewRatio=3
-XX:SurvivorRatio=n    年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:8,表示Eden:Survivor=8:1:1,一个Survivor区占整个年轻代的1/8    -XX:SurvivorRatio=8
-XX:PermSize=n    永久代初始值,默认为物理内存的1/64    -XX:PermSize=128M
-XX:MaxPermSize=n    永久代最大值,默认为物理内存的1/4    -XX:MaxPermSize=256M
-verbose:class    在控制台打印类加载信息
-verbose:gc    在控制台打印垃圾回收日志
-XX:+PrintGC    打印GC日志,内容简单
-XX:+PrintGCDetails    打印GC日志,内容详细
-XX:+PrintGCDateStamps    在GC日志中添加时间戳
-Xloggc:filename    指定gc日志路径    -Xloggc:/data/jvm/gc.log
-XX:+UseSerialGC    年轻代设置串行收集器Serial
-XX:+UseParallelGC    年轻代设置并行收集器Parallel Scavenge
-XX:ParallelGCThreads=n    设置Parallel Scavenge收集时使用的CPU数。并行收集线程数。    -XX:ParallelGCThreads=4
-XX:MaxGCPauseMillis=n    设置Parallel Scavenge回收的最大时间(毫秒)    -XX:MaxGCPauseMillis=100
-XX:GCTimeRatio=n    设置Parallel Scavenge垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)    -XX:GCTimeRatio=19
-XX:+UseParallelOldGC    设置老年代为并行收集器ParallelOld收集器
-XX:+UseConcMarkSweepGC    设置老年代并发收集器CMS
-XX:+CMSIncrementalMode    设置CMS收集器为增量模式,适用于单CPU情况。

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

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

相关文章

【Redis】3、Redis 作为缓存(Redis中的穿透、雪崩、击穿、工具类)

目录 一、什么是缓存二、给业务添加缓存&#xff08;减少数据库访问次数&#xff09;三、给店铺类型查询业务添加缓存(1) 使用 String 类型(2) 使用 List 类型 四、缓存的更新策略(1) 主动更新(2) 最佳实现方案(3) 给查询商铺的缓存添加超时剔除和主动更新的策略① 存缓存&…

泰迪智能科技基于产业技能生态链学生学徒制的双创工作室--促进学生高质量就业

据悉&#xff0c;6月28日&#xff0c;广东省人力资源和社会保障厅在广东岭南现代技师学院举行广东省“产教评”技能生态链建设对接活动。该活动以“新培养、新就业、新动能”为主题&#xff0c;总结推广“产教评”技能人才培养新模式&#xff0c;推行“岗位培养”学徒就业新形式…

Tomcat多实例部署

1、关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下2、安装好 JDK3、设置JDK环境变量4、安装 tomcat5、配置 tomcat 环境变量6、修改 tomcat2 中的 server.xml 文件&#xff0c;要求各 tomcat 实例配置不能有重复的端口号7、修改各 tomcat 实例中的 startup.sh …

更便捷的人体三维模型制作方法

人体三维模型是一种以计算机辅助设计技术为基础的创新工具&#xff0c;它在医学、生物学、运动学等领域具有广泛的应用价值。这种模型通过将人体的形态、结构与功能等要素进行数字化处理和计算&#xff0c;能够以立体图像的形式展现出来。它可以精确地模拟人体的各种部位&#…

【C】数据在内存中的存储

前言 > 在内存中&#xff0c;整型和浮点型存储的方式是不同的&#xff0c;从内存中读取的方式也是有所差异的&#xff0c;这篇文章主要介绍整型和浮点型在内存中存储的方式。 整型在内存中的存储 计算机中有符号数有3种表示方式&#xff1a; 原码&#xff1a;直接将二进制按…

查看虚拟机主机IP

虚拟机主机ip 文章目录 ifconfigip addr图形化界面 ifconfig 失败了 ip addr 图形化界面

Windows远程连接linux中mysql数据库

我没有mysql并且没有把mysql配置到环境变量中&#xff0c;所以现在我要下载mysql 一.下载mysql Mysql官网下载地址&#xff1a;https://downloads.mysql.com/archives/installer 二.安装mysql 1. 选择设置类型 双击运行mysql-installer-community-8.0.26.msi&#xff0c;这…

MySQL简单查询操作

系列文章目录 前言SELECT子句SELECT后面之间跟列名DISTINCT,ALL列表达式列更名 WHERE子句WHERE子句中可以使用的查询条件比较运算特殊比较运算符BETWEEN...AND...集合查询&#xff1a;IN模糊查询&#xff1a;LIKE空值比较&#xff1a;IS NULL 多重条件查询 ORDER BY子句排序复杂…

【基于容器的部署、扩展和管理】3.10 云原生容器运行时环境和配置管理

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 第三章&#xff1a;【3.1 容器编排系统和Kubernetes集群的构建】 第三章&#xff1a;【3.2 基于容器的应用程序部署和升级】 第三章&#xff1a;【3.3 自动…

Anaconda详细安装及配置教程(Windows)

Anaconda详细安装及配置教程&#xff08;Windows&#xff09; 一、下载方式1、官网下载2、网盘下载 二、安装三、配置四、创建虚拟环境 一、下载方式 1、官网下载 点击下载 点击window下载即可。 2、网盘下载 点击下载 二、安装 双击运行 点next 点I agree next 如…

专项练习21

目录 一、选择题 1、下列逻辑表达式的结果为false的是&#xff08;&#xff09; 2、请问以下JS代码输出的结果是什么&#xff1f; 3、以下哪些对象是Javascript内置的可迭代对象&#xff1f; 二、编程题 1、找到数组参数中的最大值并返回。注意&#xff1a;数组中只包含数字 …

OpenCV读取一张8位无符号四通道图像并显示

#include <iostream> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include

GreenPlum分布式集群部署实战

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

Django实现简单的音乐播放器 3

在原有音乐播放器上请求方式优化和增加加载本地音乐功能。 效果&#xff1a; 目录 播放列表优化 设置csrf_token 前端改为post请求 视图端增加post验证 加载歌曲 视图 设置路由 模板 加载layui css 加载layui js 增加功能列表 功能列表脚本实现 最终效果 总结 播…

Vue 如何简单快速组件化

文章目录 前言相关文章组件化实战如何引入组件什么是父组件&#xff0c;什么是子组件如何实现给子组件赋值完整代码 如何调用子组件方法完整代码 总结 前言 为了简化拆分复杂的代码逻辑&#xff0c;和实现代码的组件化&#xff0c;封闭化。我们需要使用组件化的方法。我这里只…

SDN-OpenDaylight与Mininet的原理、安装、使用

一、前言 本文将介绍OpenDaylight与Mininet的原理并介绍他们的安装及简单的使用&#xff0c;本实验的环境为Liunx Ubuntu 16.04&#xff0c;已成功安装OVS&#xff0c;但没有安装Mininet。 二、原理 &#xff08;一&#xff09;OpenDaylight OpenDaylight是一个软件定义网络&…

天猫数据分析工具(天猫实时数据)

后疫情时代&#xff0c;聚会、聚餐与送礼热度上涨&#xff0c;酒类产品既作为送礼首选又作为佐餐饮品的热门选手也受此影响迎来消费小高峰。在此背景下&#xff0c;白酒市场也开始复苏并不断加快速度。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;2023年1月份至4月…

C# 简述.NET中堆和栈的区别

目录 一&#xff0c;引言 二&#xff0c;.NET的堆栈 三&#xff0c;.NET中的托管堆 四&#xff0c;.NET中的非托管堆 五、堆栈、托管堆和非托管堆的比较 六&#xff0c;总结 一&#xff0c;引言 .NET提供了垃圾回收机制&#xff0c;使程序员从内存管理中被解放出来。但这…

4.2 x64dbg 针对PE文件的扫描

通过运用LyScript插件并配合pefile模块&#xff0c;即可实现对特定PE文件的扫描功能&#xff0c;例如载入PE程序到内存&#xff0c;验证PE启用的保护方式&#xff0c;计算PE节区内存特征&#xff0c;文件FOA与内存VA转换等功能的实现&#xff0c;首先简单介绍一下pefile模块。 …

【Web3】Web3连接到以太坊网络(测试网、主网)

目录 什么是Web3 Web3项目连接以太坊网络 1.下载Web3 2.实例化Web3对象 3.infura 获取连接以太坊网络节点 4.添加网络节点 什么是Web3 web3.js开发文档&#xff1a;web3.js - Ethereum JavaScript API — web3.js 1.0.0 documentation web3.js 中文文档 : web3.js - 以…