JVM总结
1. 内存结构
线程私有区
程序计算器
- 作用:是一块较小的内存空间,存储的是当前线程所执行的字节码文件的序号
- 特点:线程私有,不会出现内存空间溢出
虚拟机栈
虚拟机栈是管理JAVA方法执行的内存模型,每个方法执行时都会创建一个当前栈桢,在当前栈桢里面存储方法的局部变量表,操作数栈,动态链接方法,返回值,返回地址等信息,栈大小决定了方法调用的可达深度(递归多少层,嵌套调用多少层其他方法,在idea中,-Xss参数可以设置虚拟机栈的大小)
- 是线程私有的
- 局部变量表存放了编译期可知的所有基本数据类型(byte,short,int,long,float,double,boolean,char),以及对象引用
- 栈太小或者方法调用过深都将抛出StackOverFlowError异常
本地方法栈
为本地语言服务的栈,Native方法服务
线程共享区
堆内存
存放对象实例的区域,对象,数组,以及常量池(从java7开始常量池也会使用堆内存)
堆内存从GC角度可以分为:新生类(Eden区,From Survision区和To Survision区),老年代,永久代(在Java8的时候被移除了)
特点:是线程贡献,需要考虑线程安全问题,同时会产生内存溢出问题
-Xms 设置最小堆内存大小(不能小于1024K)
-Xmx:设置最大堆内存大小(不能小于1024K)
方法区
用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后代码等数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oeNxJfex-1677507866501)(null)]
特点:
- 是一块线程共享的内存区域
- 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出的错误
- 现在说的方法区一般是指元数据区(元空间Metaspace,java8的时候添加的),如果不指定大小,默认情况下,虚拟机会耗尽系统的可用内存
堆栈的区别
- 存储的东西不同,栈内存存储局部变量和方法调用,而堆内存存储对象,包括成员变量,局部变量,还有类变量
- 共享不同,栈内存是线程私有的,堆内存是所有线程共有的
- 异常错误不同:栈空间不足:java.lang.StackOverFlowError,堆空间不足:java.lang.OutOfMemoryError。
- 大小不同,栈空间小于堆空间
获取堆内存数据
java.lang.Runtime类中包含了与内存先关的方法
获取剩余空间的的字节数:Runtime.freeMemory()
获取总内存的字节数:Runtime.totalMenory()
2. 垃圾回收
垃圾回收机制
在Java中,程序员不需要显示的去释放一个对象的内存,而是由虚拟机自动去执行,在JVM中,有一个垃圾回收线程,他是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者在堆内存不足时才会触发执行,扫描那些被视为垃圾的对象,将他们添加到回收的集合中进行回收,也可以进行手动回收,通过System.gc(),通知GC运行
垃圾回收算法
-
标记清除法
标记出所有需要回收的对象,在标记完成后,统一回收的被标记的对象
优点:速度比较快
缺点:会产生内存碎片,碎片过多,仍会使得连续空间变少
-
标记整理
标记出所有需要回收的对象,在标记完成后统一进行整理,将存活对象进行一端移动,减少内存碎片,效率相对较低
优点:无内存碎片
缺点:效率较低
-
复制算法
开辟两份大小相等的空间,一份空间始终空着,垃圾回收时将存活对象拷贝进空闲时间
优点:无内存碎片
缺点:占用空间多
-
分代回收
根据对象的存活周期不同,将对象划分为几块,比如堆内存的新生代和老年代,然后根据各个年代的特点采用最合适的算法进行回收;
新生代对象的存活时间比较短,因此使用的是复制算法,老年代对象存活的时间比较长,因此使用的是标记清除或者标记整理
分代垃圾回收的过程
分代垃圾回收器分两个区,新生代和老年代,新生代默认占1/3,老年代占2/3
新生代使用复制算法,新生代里面又分3个区(Eden,To Survivor, From Survicior)默认占比是8:1:1,当Eden区满了之后就会触发第一次MinorGC,将Eden区和From区存活的对象复制到To Survivor区域,然后to Survivor区域和From Survivor互换,原来的To Servivor区域成为下一次的From Survivor区域,然后清空Eden和From Survivor区中的对象,From中的对象每经过一次MinorGC,他的年龄值就会加1,达到15的移动到老年代,这里使用了复制算法,老年代满了或者是超过了临界值则会触发完全垃圾回收
判断一个对象是否为垃圾
引用计数法
堆中每个对象实例都有一个引用计数,当一个对象被创建的时候,且将这个对象实例分配给一个变量,该变量计数设置为1,当任何其他变量被赋值为这个对象的引用时,计数加1,但当一个对象实例的某个引用超过了生命周期,或者被设置为一个新值时,这个对象实例的引用计数将会减1,任何引用计数为0的对象都是可以被当做垃圾收集的对象,也就是一个垃圾,引用计数法容易产生循环引用的问题,如果两个对象相互引用,那么他们的引用就会一直存在,导致一直无法回收,为了解决这个问题,下面引入了可达性分析法
可达性分析算法
可达性分析算法又叫做根搜索法,就是通过一系列的称之为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径被称为(Reference Chain)影响链,当一个对象到GC Roots没有任何链相连时(即从 GC Roots节点到该节点是不可达的),则这个对象就是可以被当做垃圾收集的对象,也就是一个垃圾
可以被作为GC Roots的对象
- 虚拟机栈中引用的对象
- 方法区静态成员的引用对象
- 方法区常量的引用对象
- 本地方法栈引用的对象
引用类型
-
强引用
默认声明的就是强引用,只要强引用存在,垃圾回收器就永远不会回收该对象,哪怕内存不足时也不会去回收,所以强引用是造成Java内存泄漏的主要原因,如果想回收某个对象可以将值赋值为null,切断强引用关系
-
软引用:一些非必需但是仍有用的对象,通过SoftReference实现,在内存足够的时候,软引用对象不会回收,在内存不足时则会回收,当回收了软引用对象内存还是不足时,会抛出内存溢出异常
-
弱引用:比软引用的引用强度更低一些,通过WeakReference实现,无论内存是否足够,JVM都会被进行垃圾回收
-
虚引用:最弱的引用关系,通过PhantomReference类实现,每次垃圾回收都会被回收,主要用于跟踪对象的垃圾回收状态,虚引用的对象始终返回一个null,虚引用对象始终和引用队列一起使用,当一个对象还存在虚引用时,会被加入到引用队列中,jvm通过引用队列是否包含这个虚引用来了解这个对象是否将要被进行垃圾回收
3. 对象分配
对象在内存中如何分配
对象优先在Eden区中分配,当Eden区没有足够的空间时,会触发垃圾回收,把存活的对象移动到Survicor空间,如果Survivor空间也满了,则会把部分对象移动到老年代中,如果对象太大,是一个大对象,则这个对象会直接分配到老年代,不会发生GC
对象如何从年轻代进入老年代
- 对象年龄够老,默认是15,可以通过XX:MaxTenuringThreshold设置,复制到老年代,同时年龄加1
- 大对象会直接分配到老年代,大对象的定义和具体的JVM版本,堆大小,垃圾回收策略有关,一般为2K~128k,可以通过XX:pretenureSizeThreshold设置其大小
4. 垃圾收集器
JVM针对新生代和老年代分别提供了不同的垃圾收集器,新生代有Serial,ParNew,Parallel Scavenge,针对老年代提供的垃圾收集器有Serial Old,Parallel Old,CMS,还有针对不同区域的G1分区收集算法
常见的垃圾收集器
Serial垃圾收集器
Java虚拟机运行在Client模式下的新生代的默认垃圾收集器,基于复制算法实现,是一个单线程收集器,在进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束,Serial收集器对于但CPU运行环境来说,没有线程交互开销,可以获得最高的单线程垃圾收集效率
ParNew垃圾收集器
Java虚拟机运行在Server模式下,新生代的默认垃圾收集器,基于复制算法实现,采用多线程模式工作,在进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束,ParNew垃圾收集器默认开启与CPU同等数量的线程进行垃圾回收,可以通过-XX:ParallelGCThreads参数调节工作线程数
Parallel Scavenge垃圾收集器
Parallel Scavenge垃圾收集器是为提高新生代垃圾收集效率而设计的垃圾收集器,基于复制算法实现,采用多线程,在系统吞吐量上有很大的优化,,可以更高效的利用CPU完成垃圾回收任务,Parallel Scavenge提供了三个参数用于调节,控制垃圾回收的停顿时间及吞吐量,分别是:控制足最大垃圾收集停顿时间:-XX:MaxGCPauseMillis,控制吞吐量大小:-XX:GCTimeRation,控制是否开启自适应调节策略:UseAdaptiveSizePolicy
Serial Old垃圾收集器
Serial Old是JVM运行在Client模式下,老年代的默认垃圾收集器,Serial Old是Serial的老年代实现,同Serial一样采用单线程执行,不同的是Serial Old基于标记整理算法实现
Parallel Old垃圾收集器
Parallel Old垃圾收集器采用多线程并发进行垃圾回收,基于标记整理法实现,在设计上优先考虑系统吞吐量,其次考虑停顿时间等因素
CMS垃圾收集器
CMS垃圾收集器是为老年代设计的垃圾收集器,其主要目的是达到最短时间的垃圾回收停顿时间,基于线程的标记清除算法实现
CMS的垃圾回收过程包含4个过程
- 初始标记:只标记GC Roots直接关联的对象,速度很快,需要暂停所有工作线程
- 并发标记:和用户一起工作,执行GC Roots跟踪标记过程,不需要暂停工作线程
- 重新标记:为了确保并发标记的正确性,重新标记已经标记的对象,需要暂停工作线程
- 并发清除:和用户线程一起工作,执行清除GC Roots不可达对象的任务,不需要暂停工作线程
G1垃圾收集器
G1垃圾收集器是为了避免全区域垃圾收集引起的系统停顿,将堆内存划分大小固定的几个独立区域,独立使用这些区域跟踪垃圾收集进度,同时在维护一个优先级列表,根据系统允许的最长垃圾收集时间,优先回收垃圾最多的区域,相对于CMD垃圾收集器,G1垃圾收集器不产生内存碎片,可以精确的控制停顿时间,在不牺牲吞吐量的前提下实现停顿垃圾回收
G1垃圾回收器的几个重要参数
- -XX:MaxGCPauseMillis:暂停毫秒级,默认200毫秒
- -XX:G1HeapRegionSize:区域大小,默认最多2048块,每块的大小需要为2的幂次方,最大为32M
- -XX:G1NewSizePercent:新生代的最低百分比,默认5%
- -XX:G1MaxNewSizePercent:新生代的最大百分比,默认60%
5. 类加载器
类加载器负责将class文件加载到java虚拟机中,并为之创建一个Class对象
类加载器的流程
- 加载:将class文件加载到内存中,将静态数据结构转化成方法区中运行时的数据结构,在堆中生成一个代表这个类的对象,作为数据访问的入口
- 验证:确保加载的类符合JVM规范和安全,保证被效验类的方法在运行时不会做出危害虚拟机的事件,做一个安全检查
- 准备:为static变量在方法区中分配内存空间,设置变量的初始值,注意只设置静态变量,不包括实例变量,实例变量在对象初始化时赋值
- 解析:虚拟机将常量池内的符号引用替换为直接引用的过程,符号引用中的符号可以是任何形式的字面量,只要能无歧义的定位到目标即可,直接引用是可以直接指向目标的指针,相对偏移量或者间接定位到目标的句柄
- 初始化:初始化类变量和其他资源
- 使用
- 卸载:GCh将对象从内存中卸载
常用的类加载器
- 启动类加载器(Bootstrap ClassLoader):虚拟机内置类加载器,加载java核心类库,如JAVA_HOME/jre/lib/rt.jar,resources.jar,sun.boot.class.path,使用C+/C++实现,他没有父类加载器,是扩展类加载器和应用程序加载器的父类加载器
- 扩展类加载器(Extension classLoader):由java语言编写,从系统属性java.ext.dirs目录中或者JDK安装目录JRE/lib/ext加载类库
- 应用程序类加载器(Application ClassLoader):应用程序类加载器,负责加载用户类路径上所指定的类,我们程序中默认的类加载器,可以通过ClassLoader#getSystemClassLoader()获取并操作这个加载器
双亲委派机制
双亲委派机制是当一个类加载器需要加载一个字节码文件时,首先会把这个任务委托给他的上级类加载器,上级类加载器又交给他的上级,以此递归,直到上级类加载器不能加载该字节码文件,然后再自己去加载这个字节码文件,如果自己也无法加载则抛出ClassNotFoundException异常,这样做的好处是防止一个字节码文件多次加载,保证了数据的安全性,即使重复加载了也不会是同一个class对象
6. JVM调优
在调优之前要先明确是否需要使用JVM调优,因为大多数Java应用是不需要调优的,大多数导致GC问题的原因是代码层面的问题,比如创建的对象数量过多,使用了大量的全局变量和大对象
需要调优的场景
- Heap内存(老年代)持续上涨,达到设置的最大内存值
- Full GC次数频繁
- GC停顿时间过长
- 应用出现OutOfMemory等内存异常
- 系统吞吐量不高
调优步骤
- 分析GC日志和Demp文件,判断是否需要优化,确定瓶颈问题点
- 确定JVM调优量化目标
- 调整JVM调优参数,包括内存,延迟,吞吐量
- 观察调优前后的差异,不断分析和调整,找到最合适的参数
- 将这些参数应用到服务器
调优参数
语法
- -XX:+ ’ +'表示启用该选项
- -XX:- '-'表示关闭该选项
- -XX:= '='给选项设置一个数字类型的值,可跟随单位,例如:m和M表示兆字节,k和K表示k字节,g和G表示千兆字节
参数示例
-Xms4g:设置最小堆内存大小为4g,堆内存初始大小
-Xmx4g:设置最大堆内存大小为4g,堆内存最大值
-Xmn1200m:设置年轻代大小为1200MB,增大年轻代后,将会减小老年代的大小,这个值对系统性能较大,官方推荐配置为整个堆的3/8
-Xss512K:设置每个线程的堆栈大小,JDK5.0后每个线程堆栈大小为1MB,以前为256K,值越小,能创建的线程越多
-XX:NewRatio=4:设置年轻代与老年代的比值为1:4,年轻代占整个堆栈的1/5
-XX:SurvivorRatio=8:设置年轻代中Eden区和Survivor区的比值为2:8,一个Survivor区占整个年轻代的1/10
-XX:MaxTenuringThreshold=15:设置Survivor区中对象年龄的最大值为15,超过这个值则进入老年代,如果设置为0,则年轻代不经过Survivor,直接进入老年代
-XX:+UseParNewGC:年轻代
-XX:+UseConcMarkSweepGC:老年代
常用调优参数
-Xms:初始化堆内存大小,默认为物理内存的1/64(小于1G)
-Xmx:堆内存的最大值。默认(MaxHeapFreeRation参数可以调整)空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制
-Xmn:新生代大小,包括Eden和两个Survivor区
-XX:MaxDirectMemorySize=1G:直接内存,报java.lang.OutOfMemoryError:Direct buffer memory异常时可以上调这个值
-XX:+DisableExplicitGC:禁止运行期间显示的调用System.gc()来触发full GC
-XX:CMSlnitiatingOccupancyFraction=60:老年代内存回收阈值,默认为68
-XX:ConcGCThreads=4:CMS垃圾回收器并行线程数,推荐值为CPU核心数
-XX:ParallelGCThreads=8:新生代并行收集器的线程数
-XX:MaxTenuringThreshold=10:Survivor区的最大年龄值,超过就会进入老年代
相关文章:

JVM总结
1. 内存结构 线程私有区 程序计算器 作用:是一块较小的内存空间,存储的是当前线程所执行的字节码文件的序号特点:线程私有,不会出现内存空间溢出 虚拟机栈 虚拟机栈是管理JAVA方法执行的内存模型,每个方法执行时都…...

AOF:redis宕机,如何避免数据丢失
由于redis是基于内存的数据库,一旦宕机,数据就会丢失?如何解决? 目前,Redis 的持久化主要有两大机制,即 AOF(Append Only File)日志和 RDB(Redis DataBase) 快照。 AO…...

LC-3—MIO、MMIO、Caller Save、Callee Save
LC-3—MMIO、Caller Save、Callee SaveMMIOCaller Save、Callee Save举个例子MMIO MMIO(Memory Mapped I/O)是一种在系统内存中映射I/O端口的技术,它允许设备直接访问内存中的特定地址,从而实现I/O操作。MMIO技术可以提高I/O操作…...

SQL注入报错注入之floor()报错注入原理分析
简介 对于SQL注入的报错注入通常有三个函数需要我们掌握: extractValue(xml_frag, xpath_expr)updateXML(xml_target, xpath_expr,new_xml)floor() 对于extractValue和updateXML函数来说比较好理解,就不做解释了,这里只对floor函数的报错注…...

2023CS双非保研985经验分享(南大、华科、中科大科学岛、国防科大、西交、中南、深圳大学、北邮、中科院等)
前言: 2022保研以来,因为自己的双非背景,要与985、211的排名靠前的计科大佬竞争,不自信、焦虑无时无刻的包围着我;所幸,一路以受到了许多学长、学姐耐心的帮助,也有很多保研的同学一路互相支撑。…...
Shell中的IFS
IFS是shell的内置变量,IFS是一个字符串,里面的每一个字符都会用来作为分隔符进行单词分割。 IFS变量只在当前shell起作用。 一、对$*的影响 先做参数替换把$*替换成参数列表。相当于args[] 然后下面分两种情况: (1)…...
Java学习线路图--书籍推荐
----基础---- 《Java从入门到精通》 ----进阶---- 一 《Java项目开发全程实录》《Java开发实例大全(基础篇)》《Java开发实例大全(提高篇)》 二 《Java Web从入门到精通》《Java Web项目开发全程实录》《Java Web开发实例大…...

【GO】k8s 管理系统项目23[前端部分–工作负载-Pod]
k8s 管理系统项目[前端部分–工作负载-Deployment] 1. 代码部分 1.1 准备工作 由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改. 替换Deployment为Pod替换Deploy为Pod替换deployment为pod替换deploy为pod禁用新增的按钮,删除新增方法,表…...

rabbitmq在linux系统下安装步骤
第一步:登录官网 官网地址:www.rabbitmq.com,点击Get Started 重要信息:RabbitMQ Tutorials手册,描述了工作模式 第二步:点击Download Installation下载 重要信息:rabbitmq是用erlang语言开发的࿰…...

阿里测试员晒薪资条,看完真的扎心了...
前几天,有位老粉私信我,说看到某95后学弟晒出阿里的工资单,他是真酸了…想狠补下技术,努力冲一把大厂。 为了帮到他,也为了大家能在最短的时间内做面试复习,我把软件测试面试系列都汇总在这一篇文章了。 …...
内网渗透辅助工具集Yasso
目录 介绍 工具优势 程序功能模块 目前已有用功能模块 使用例子 工具下载</...
Spring笔记(1):概述
1、什么是Spring? Spring是最受欢迎的企业级Java应用程序开发框架,使用它创建性能好、易于测试、可重用的代码。Spring是一种轻量级的框架。Spring框架的核心特性是开发任何Java应用程序,其目标是使得J2EE开发变得更容易,通过启用…...

工程机械焊接件焊接结构件三维扫描检测外观质量控制-CASAIM三维扫描检测仪
焊接已发展为制造业中的一种重要的加工方法,广泛应用于航空、航天、冶金、石油、汽车制造以及国防等领域。工程机械焊接件品种繁多、几何形状复杂,焊接件质量的好坏将直接影响到产品的使用寿命长短。对焊缝表面尺寸测量及评定表面焊缝缺陷时,…...

使用linux部署项目步骤
文章目录前言一、服务器环境配置二、数据库导入三、项目打包1、修改项目中的访问路径2、修改db.properties的数据库访问路径3、打包4、修改配置,启动服务四、测试总结前言 今天学习了在服务器中部署项目,记录一下 一、服务器环境配置 首先要安装VMware&…...
pt02-list-tuple-dir
容器类型 通用操作 数学运算符 (1) 用于拼接两个容器 (2) 用原容器与右侧容器拼接,并重新绑定变量 (3) * 重复生成容器元素 (4) * 用原容器生成重复元素, 并重新绑定变量 (5) !:依次比较两个容器中元素,一但不同则返回比较结果。< < > > 意…...

高端电器新十年,求解「竞速突围」
竞争激烈的高端电器品牌们,平时王不见王,但也有例外。海尔、博西、海信、创维、方太、老板等等近乎中国电器行业所有一线品牌副总裁级别以上高层,2月22日都现身于上海,来参加一场由红星美凯龙攒起来的高端电器局,2023中…...

[Android Studio] Android Studio使用keytool工具读取Debug 调试版数字证书以及release 发布版数字证书
🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪 Topic 发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 📋笔记目…...

2023年金三银四必备软件测试常见面试题1500问!!!【测试思维篇】
五、测试思维5.1 打电话功能怎么去测?我们会从几个方面去测试:界面、功能、兼容性、易用性、安全、性能、异常。1)界面我们会测试下是否跟界面原型图一致,考虑浏览器不同显示比例,屏幕分辨率。2)功能&#…...

推荐四款自用的电脑神器
作为一个经常鼓捣电脑的小编来说,无论是写文章、截图、办公方面都缺少不了一些好用的软件,今天就给大家盘点一些我推荐用的办公效率工具,让你的效率事半功倍。 写文章神器 以前写文章一直是在公众号编辑上直接写的,缺点就是格式有…...

CSDN 竞赛 32 期
CSDN 竞赛 32 期1、题目名称:传奇霸业2、题目名称:严查枪火3、题目名称:蚂蚁家族4、题目名称:运输石油小结1、题目名称:传奇霸业 传奇霸业,是兄弟就来干。 小春(HP a)遇到了一只黄金哥布林(HP x)。 小春每…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...