JAVA中的垃圾回收器(3)----ZGC
一)ZGC介绍:是JAVA11新引入的低延迟垃圾收集器
ZGC是一款基于Regin的,暂时没有分代概念的,使用了读屏障,颜色指针等技术来实现并发的标记清除和标记整理算法,一低延迟为主要目标的一款垃圾回收器
ZGC的regin可以分为是下图中具有大中小三类容量
1)小型regin:容量固定是2MB,用于存放小于256K的小对象
2)中型regin:容量固定是32MB,用于存放大于等于256KB但是小于4MB的对象
3)大型regin:容量不固定,可以动态变化,但必须是2MB的整数倍,用来存放4MB以上的大对象,但是他的实际容量可能小于中型regin,大型regin在进行ZGC的时候是不会被重分配的,重分配是ZGC的一种处理动作,用于复制对象的收集器阶段,因为复制一个大对象的代价非常高昂;
uma:所有CPU都是统一访问这一块内存,如果多核CPU来争抢同一块内存,那么此时就会涉及到线程安全问题,可能涉及到内存资源分配争抢的问题,可能会有争抢或者是CAS机制影响程序性能,尽管TLAB做一些内存分配增强的优化
UMA代表内存只是存在一块,所有的CPU都去访问这一块内存,那么就会存在竞争问题来争抢内存总线访问权,有竞争就会有锁,有锁效率就会受到影响,而且CPU核数越多,竞争就越激烈;
numa:是CPU访问内存的一个架构,统一内存访问架构,将一个大堆内存分开成一小块一小块的内存来供给每一块供给某一个CPU来优先进行访问,避免了大多数分配内存和使用内存的资源争抢问题,ZGC可以自动识别NUMA架构
NUMA的话每一个CPU对应这一块内存,况且这块内存在主板上是离CPU是很近的,每一个CPU来优先访问这块内存,那么效率自然就提高了,服务器的NUMA架构在中大型系统上一直非常盛行,也是高性能的解决方案,尤其在系统延迟方面表现都很优秀,ZGC是能自动感知NUMA架构并充分利用NUMA架构特性的;
ZGC的优缺点:
1)支持TB级别的堆:生产环境的硬盘还没有上TB呢,可以满足未来十年内,JAVA应用的所有需求了;
2)最大GC停顿时间不超过10ms:垃圾回收几乎实现了全局并发执行;
3)未来GC奠定的基础
4)停顿时间不会随着对增大而增大,也就是说几十G堆的停顿时间是10ms以下几百G甚至是上TB级别的堆停顿时间也是10ms以下;
缺点:
1)只是适用于32位系统
2)最大只是支持4TB内存容量
3)最糟糕的情况下吞吐量会下降15%,这都不是事至于吞吐量,通过扩容分分钟解决
4)分代的原因:不同对象的生命周期不相同,可能会扫描整个堆
如果堆空间越来越大,那么垃圾回收的造成的STW的时间会呈现线性的增长
堆空间分页模型:小页面优先回收,大页面尽量不回收
ZGC本身只是支持三种页面,分别是小页面,中页面,大页面,其中小页面指的是2MB的内存空间,中页面指的是32MB的内存空间,大页面指的是操作系统分配的大页
当对象大小小于等于256KB时,对象分配在小页面,当对象大小在256KB和4M之间,对象分配在中页面,当对象大于4M,对象分配在大页面,ZGC对于不同页面回收的策略也不同。简单地说,小页面优先回收;中页面和大页面则尽量不回收;
1)ZGC会自动识别NUMA架构,把一块大的内存拆分成若干个小内存来提供个不同的CPU来进行使用,每一块内存会让一个CPU优先访问;
2)ZGC小页面优先回收,大页面尽量不回收,可以选取垃圾特别多的页面进行回收,一个页面垃圾越多,那么回收的优先级就越高,如果将所有的页面都进行回收,那么回收的效率就特别低;
ZGC中的转移:如果是同一个页面等同于标记整理算法,如果是不同的页面,等同于复制算法
标记:从根集合出发,标记活跃对象,此时内存存在着活跃对象和死亡对象
转移:把活跃对象转移复制到新的内存上面,原来的内存空间可以回收
重定位:因为对象的内存地址发生了变化,所以所有的指向对象的老地址的指针都要调整到对象的新的地址上面
三色标记漏标:就是用来修复并发标记中的漏标记问题,就是将B扫描完成之后,B就会变成黑色,此时B引用着D,D引用着E,此时如果在并发标记过程中D指向E的指针没了(D还没有来得及指向E),此时B指向了E,此时因为B已经变成了黑色,B不会重新扫描,但是此时的E就变成了一个垃圾对象,此时就发生了漏标操作CMS使用的是增量更新G1使用的是原始快照
B C D此时扫描完成,变成绿色,M0标记位是1,此时假设B C D 扫描完成之后发现B对象指向了D对象,此时D被其他对象指向了,但是此时B不会被扫描了,此时就出现漏标的情况,此时D就是蓝色的对象就被认为是垃圾,并发标记完成变成绿色;
二)指针着色技术:
虚拟机栈(栈帧中的本地变量表)+方法区中类的静态变量+方法区中的常量+本地方法栈
1)颜色指针是ZGC的核心概念,因为zgc在指针中借了几位来搞事情,所以它必须要求在64位的系统上,2^10=1K,2^20=1G,2^32=4G,64位系统可以达到4TB;
2)在ZGC中使用低42位来表示使用中的堆空间(真实内存),ZGC借助高几位来做GC相关的事情,快速实现垃圾回收中的并发标记,转移和重定位等等;
3)这几个标记位具有互斥性,这几个标志位有且只有一个位置为1,某一个标志位为1表示有颜色;
4)ZGC只是支持64位系统,64位指针,ZGC中低42位表示的是堆空间的地址范围,因为42位是4个T,ZGC借助高几位来实现做GC垃圾回收相关的事情,用于快速实现垃圾回收中的并发标记,转移和重定位等,这几个高位是存在互斥性的,这几个位置有且只能有一个位置置为1,只要这个位置是1,那么指针就会带有颜色,颜色指针表示的是某一个比特位是1了,那么就代表着这个指针带有颜色了,在进行垃圾回收的时候,和对象头就没有关系了,其他的垃圾回收器在进行垃圾标识的时候会把垃圾的状态写到对象头里面,但是在ZGC里面它使用的不是对象头而是指针的着色技术;
System.gc()会被很多垃圾回收器不一定会调用;
颜色指针的概念:CMS和以前的垃圾回收器是标记在对象内部的,但是ZGC是标记在指向对象的引用上面,内部会分配4个比特位专门去做标记,这就叫做颜色指针,下面是初始状态,GC垃圾回收器还没有启动:
1)初始情况下,A,B,C,D在堆上面的不同地址中,为了方便演示,对象地址就使用1-9来表示,况且都被GCROOTS引用给关联着
2)G1垃圾回收器没有启动的时候如果new 对象,那么指针的颜色就是蓝色,也就是Remapped他的标记位就是1,这个对象已经完成重定位,当指针内存地址指向真正的对象的内存地址,那么此时Remapped标记为就是1,就是刚刚new出来的对象或者是垃圾回收器已经转移完成的对象(已经完成重定位);
三)ZGC的垃圾回收过程:
Remapped代表蓝色表示已经完成并发转移(在垃圾回收器启动以前)并且更新完成指针的对象(并发转移移动到新区域以后被标记成蓝色),在最终标记以后开始并发转移以前蓝色的对象是没有标记过的对象垃圾对象
M0:本次垃圾回收过程中或者是上一次垃圾回收中被标记的对象,区分两次垃圾回收
M1:本次垃圾回收过程中或者是上一次垃圾回收中被标记的对象,区分两次垃圾回收
1)初始标记:只是进行标记GCroots直接关联的对象,此时A的颜色是绿色,M0为1表示颜色是绿色,代表已经标记过的对象,代表这本次垃圾回收对象的指针标记过的颜色,因为此时GCROOTS直接关联的对象是A,那么ZGC就把A指针直接标记成绿色,代表A已经被标记过
初始标记存在STW,但是时间很短,初始标记就是只是需要扫描所有的GCROOTS直接关联的对象;
2)并发标记:这个过程扫描引用链上面的所有对象,这段时间GC的处理时间非常长,但是没有STW,业务线程可以继续进行执行,但是会产生漏标问题;
3)重新标记:此时需要使用原始快照来解决漏标方案,会产生STW,比初始标记快,比并发标记慢一些,经过重新标记以后,整个堆内存中蓝色的对象就是垃圾对象,如果此时有新来的new对象就会被标记成蓝色;
在并发标记完成以后并发转移准备,JVM判断如果某一个对象还是蓝色况且是在旧区域,不是红色或者是绿色,那么说明这个对象压根就没有标记过,说明此时这个对象还是不可达;
ZGC将G1的筛选回收进行拆分,拆分成了三个步骤:
4)并发预备重分配:没有STW
在内部会使用一些算法,计算一下有哪些大概有哪些regin要进行清理和G1里面计算回收比例是一样的,那一块回收比例大一些就会回收哪一块,没有STW
4.1)进行分析,哪些页面有垃圾,哪些页面的垃圾有多少,占多少总页面比例,并进行分析,并针对于垃圾较多的区域优先进行回收,作为一个优先级别;
4.2)如果发现一个区域地方全是垃圾,然后可以在并发转移准备并发全部进行清理,对业务程序没有任何影响,这个阶段用户线程和垃圾回收线程一起跑;
5)初始转移:存在STW,做对象重定位
对应着初始标记的对象将GCROOTS直接关联的对象进行复制算法转移到另一个位置,初始转移的对象都是绿色的对象,将A的引用指针进行更新,并且将MO状态转换到Remapped状态,这个过程会造成STW,存在短暂的STW;
5.1)先对页面作短暂的STW,将GCROOTS直接关联的对象(地址1)A转移到小页面中的内存地址是10的地方;
5.2)跟新指向A对象的指针;
5.3)将指向A对象的指针变成蓝色(已经从初始阶段完成了并发转移),改之前是绿色的(代表完成了初始标记但是还没有完全完成并发转移),下面是初始转移完成的情况:
六)并发转移:
在以前的垃圾回收器中,这个过程都是STW的,但是ZGC却采用了转移对象采取和用户线程一起执行,ZGC额外的在堆内存维护了一张转发表,用来维护新旧地址的映射
1)使用复制算法将老对象移动到新的区域里面,此时对象的指针还是绿色,属于标记状态
2)使用转发表维护新旧对象的地址的映射,注意做对象的转移和插入转发表中的记录是原子操作,要么全部执行成功,要么全部执行失败;
3)本次并发转移过程中并不会更新新对象的地址到指针里面,就使用转发表来进行存储,当程序需要访问转发表来读取被移动的对象的时候,采用读屏障来做引用地址的更新
此时如果有新来的对象,放到新区域里面并标记成蓝色
STW:要进行重定位吞吐量会严重减少,STW时间会非常少
此时就没有必要把A放到转发表里面了,因为A已经转移完成了
并发转移:对应处理着并发标记标记的对象,转移MO标记有效,也就是绿色的对象,使用复制算法将新的对象移动到另一块空间里面,但是这个时候用户线程还在执行,如果是STW,那么在STW的时间范围内做地址的引用更新是比较简单的,但是此时并发重分配是合用户线程一起执行的,没有STW,复制算法挪完对象之后该如何更新指针原引用,这个过程就变得比较复杂了,ZGC不会马上去把引用进行更新因为修改老的引用会有严重的并发控制问题
a)复制算法复制对象到一个空区域,复制对象以后不会直接进行修改原引用的指针
b)ZGC底层使用的是读屏障也叫做内存屏障,什么修改新的引用指针呢?针对于引用做一个读取操作的时候才会修改这个指针里面的值,才会修改这个引用最新的对象的地址,并发转移最终不会终止业务线程和业务线程并发执行的,业务线程此时看到的对象的指针是不会进行修正的,此时就会发生问题,这个时候使用一个转发表,就是记录指针新旧地址的映射HashMap<老地址,新转移的地址>,那么此时如果在再次读取这个转移的对象,那么此时就可以根据转发表进行二次转发找到这个对象,但是对象转移和查转发表是原子操作的,此时A就不用记录在转发表,在初始标记阶段已经把A的指针的引用关系修改了,存在STW;
经历过并发转移以后,原有的老对象的内存空间就被清理掉了,但是B C对象指针还指向的是老对象(堆中已经不存在)的地址;
那么此时如果在第一次垃圾回收和第二次垃圾回收之间new出来的对象,此时存放到新的地址里面,标记成蓝色就是Remapped
6)并发重映射:
原来对象的其他老的引用指向的不是垃圾的对象A,现在这个对象A移动了位置,需要将那些引用指向新移动的A的对象位置,其实最终这一个步骤不做也可以,因为可以通过颜色屏障可以自动得将那些要修改的引用对象地址做一个更新,老的引用就不执行这个阶段也没啥事,这个过程放到下一次垃圾回收的并发标记阶段来做上次并发转移对象的重定位
在两次GC业务之间,访问那些没有完成并发重定位的对象所依据的就是读屏障
ZGC的第二次垃圾回收:
1)第二次垃圾回收的初始标记:标记A,M1的颜色此时是红色,这时候的红色代表的是本次垃圾回收的被标记对象指针的颜色,此时绿色的对象代表着新创建的对象和上一次没有进行进行并发转移但是没有做对象重定位更新指针的对象,此时做重定位,绿色的指针此时指向的是老地址;
2)第二次垃圾回收的并发标记:
1)首先进行标记和GCROOTS间接关联的对象就是E,E此时是蓝色,此时一定是新创建出来的对象,此时将E表标记成红色;
2)做上一次垃圾并发回收转移对象的重定位,这个时候需要做绿色指针修正,绿色不是当前垃圾回收中可达性算法标记的对象的引用指针的颜色,此时从转发表中进行查询,然后将这条记录从转发表中删除掉,然后进行更新指针重定位,将绿色的指针变成红色,这个操作是原子的,删除转发表,做对象重定位更新指针地址也是做原子操作;
更新D对象的指针;
ZGC会把两次垃圾回收关联到一起,第一次垃圾回收的并发标记阶段是没有并发重映射的过程的,第二次垃圾回收的并发标记会对上一次并发转移的并发重定位,将该对象的颜色标记成本次ZGC垃圾对象标记的颜色;
ZGC:停顿时间非常低+分页模型+标识阶段(标识垃圾)+转移阶段(对象复制或者是移动)
四)读屏障:就是向应用程序中插入一小段代码的技术,从堆中读引用,惰性更新
读屏障是JVM向应用程序代码中插入一小段代码中的技术
1)当从堆中读引用的时候,就需要加入一个读屏障
2)判断当前指针是否是上一次本次GC的标记颜色
3)修正指针:对象重定位+删除转发表的记录
1)涉及到的对象:做并发转移但是还没有做并发重定位的对象
2)触发时机:在两次GC之间业务线程频繁访问这样的对象
3)读屏障:指针对象重定位+删除转发表记录+更新对象指针(两个操作是原子操作)
4)为什么要做读屏障?
对象已经被ZGC移动,但是指针没有进行修正,应用程序访问到指针旧地址出错,但是旧地址已经没有对象了
不是涉及到的代码都触发,吞吐量降低
读屏障=更新指针
1)在进行读取指针的时候会自动进行判断是否当前对象地址发生了变化,是通过类似于CAS来进行更新地址的,在使用到引用之前会更新地址;
2)ZGC的头部信息会记录着对应的对象是否被修改和是否是可达的
3)读屏障和写屏障都会进行判断是否在GC并发阶段进行赋值的,如果是并发阶段对引用做更新,所以此时再进行增量更新和记录原始快照,只有在这个阶段才会调用写屏障的代码去记录,正常程序执行过程中赋值操作太多了,每一次都调用读写屏障代码,效率非常低
4)那么在读屏障进行的时候,程序在读取引用地址的时候?是如何判断一个对象被挪动到了另一个区域里面了呢?
5)转发表:forwaord Table,在并发重分配的过程中,要挪对象
HashMap<老地址,新地址>
而G1垃圾回收器会产生STW,等到所有的对象都被挪走了,况且所有的引用都被更新了以后,才会继续执行业务线程,刷选回收之后,所有的对象都可以使用了
五)ZGC的触发时机:
1)基于分配速率的自适应算法:是最主要的GC触发方式,其算法原理可以近似认为ZGC根据最近的对象分配速率以及GC总时间,来进行计算当内存占用达到什么阈值的时候出发下一次GC,通过ZAllocationSpikeTolerance参数控制阈值大小,该参数默认2,数值越大,越早的触发GC,日志中关键字是“AllocationRate;
2)基于固定时间间隔;定时活动秒杀等场景
3)主动触发规则:时间间隔不确定
4)阻塞内存分配请求触发:
5)System.gc()触发
6)元数据分配触发:元数据区不足时导致,一般不需要关注MetadataGCThreshold
相关文章:

JAVA中的垃圾回收器(3)----ZGC
一)ZGC介绍:是JAVA11新引入的低延迟垃圾收集器 ZGC是一款基于Regin的,暂时没有分代概念的,使用了读屏障,颜色指针等技术来实现并发的标记清除和标记整理算法,一低延迟为主要目标的一款垃圾回收器 ZGC的regin可以分为是下图中具有大…...

IDEA 如何运行 SpringBoot 项目
步骤一:配置 Maven 第一步:用 IDEA 打开项目,准备配置 maven 环境 ,当然如果本地没有提前配置好 maven,就用 IDEA 默认的配置即可 配置 maven 步骤 情况 1:如果本地没有配置过 maven,可以保持如…...

Linux MeterSphere测试平台远程访问你不会?来试试这篇文章
🎬 鸽芷咕:个人主页 🔥 个人专栏:《粉丝福利》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网…...

15.k8s集群防火墙配置
防火墙配置 ######################## # master节点防火墙设置 ######################### 所有master节点开放相关防火墙端口 $ firewall-cmd --zonepublic --add-port6443/tcp --permanent $ firewall-cmd --zonepublic --add-port2379-2380/tcp --permanent $ firewall-cmd…...

Python beautifulsoup网络抓取和解析cnblog首页帖子数据
视频版教程:一天掌握python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium 我们抓取下https://www.cnblogs.com/ 首页所有的帖子信息,包括帖子标题,帖子地址,以及帖子作者信息。 首先用requests获取网页文件࿰…...

Java集成腾讯云OCR身份证识别接口
一、背景 项目用到身份证识别获取人员信息的功能,于是想到了腾讯云提供这样的API。在整合代码过程都很顺利,利用腾讯云官方SDK很快集成进来。但是在上测试环境部署时有了新的问题,通过Nginx代理后的环境无法访问到目标腾讯云接口,…...

C++之C++11引入enum class与传统enum关键字总结(二百五十一)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

如何将word格式的文档转换成markdown格式的文档
如何将word格式的文档转换成markdown格式的文档 前言 A. 介绍Markdown和Word格式文档 什么是Markdown? Markdown是一种轻量级标记语言,旨在简化文本格式化和排版的过程。它以纯文本形式编写,通过使用简单的标记语法,使文档更具…...

Leetcode—2558.从数量最多的堆取走礼物【简单】
2023每日刷题(十二) Leetcode—2558.从数量最多的堆取走礼物 大顶堆实现代码 void swap(int *a, int *b) {int tmp *a;*a *b;*b tmp; }void downAdjustHeap(int *heap, int low, int high) {int i low;int j 2 * i 1;while(j < high) {if(j …...

【如何写论文】硕博学位论文的结构框架、过程与大纲分析
硕士论文可以说是毕业前最重要的一部分,也可以说是展示和检验你3年研究生学习的成果的一个考试。硕士论文答辩和检验合格,才能够顺利拿到毕业生和学位证,可见其重要性。 目录 一、基础框架1.1、摘要(Abstract)1.2、绪论…...

砷化镓(GaAs)纳米线 砷化镓纳米线 GaAs纳米线 瑞禧
砷化镓(GaAs)纳米线 名称:砷化镓(GaAs)纳米线 直径:50-400 nm 长度:10-80μm 纳米线是一种新型的材料结构,具有较小的直径和高的长度比,因此在纳米电子学、光电器件等领域有着广泛的应用前景…...

PostGreSQL:JSON|JSONB数据类型
JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)JSON 是轻量级的文本数据交换格式JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许…...

树----数据结构
树的概念 树是一种非线性的数据结构,它是由 n (n>1) 个有限结点组成一个具有层次关系的集合,它看起来就像一颗倒挂的树,根朝上,叶朝下。由 0 个节点构成的树,叫做空树。 树的特点:每个结点有 0 个或多…...

GitLab定时备份
GitLab定时备份 文章目录 GitLab定时备份GitLab基础环境备份命令自动清理备份上传命令设置定时任务参考链接 GitLab基础环境 部署方式:Docker 版本:16.2.2 备份命令 Notes: 编写sh脚本时,不要使用Windows上的Notepad类似编辑…...

SQL IN 运算符
SQL IN 运算符 IN 运算符允许您在 WHERE 子句中指定多个值。 IN 运算符是多个 OR 条件的简写。 SQL IN 语法 SELECT column_name(s) FROM table_name WHERE column_name IN (value1, value2, ...); 或者 SELECT column_name(s) FROM table_name WHERE column_name IN (SELE…...

虚拟机构建单体项目及前后端分离项目
引言 在现代化办公环境中,会议是组织沟通、决策和合作的重要方式之一。为了提高会议的效率和质量,许多企业选择部署会议OA系统来实现会议管理的自动化和数字化。本博客将介绍如何部署和优化会议OA系统,并探讨前后端分离的SPA项目在此过程中的…...

代码浅析DLIO(一)---整体框架梳理
0. 简介 我们刚刚了解过DLIO的整个流程,我们发现相比于Point-LIO而言,这个方法更适合我们去学习理解,同时官方给出的结果来看DLIO的结果明显好于现在的主流方法,当然指的一提的是,这个DLIO是必须需要六轴IMU的&#x…...

Springboot的Container Images,docker加springboot
Spring Boot应用程序可以使用Dockerfiles容器化,或者使用Cloud Native Buildpacks来创建优化的docker兼容的容器映像,您可以在任何地方运行。 1. Efficient Container Images 很容易将Spring Boot fat jar打包为docker映像。然而,像在docke…...

c 从avi 视频中提取图片
avi 视频的视频流编码必须是jpeg,或者mjpg 直接用摄像头录取的视频都是这两种格式,不能用ffmpeg转成avi的视频。 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.…...

Jtti:Apache服务的反向代理及负载均衡怎么配置
配置Apache服务的反向代理和负载均衡可以帮助您分散负载并提高应用程序的可用性和性能。下面是一些通用的步骤,以配置Apache反向代理和负载均衡。 1. 安装和配置Apache: 确保您已经安装了Apache HTTP服务器。通常,Apache的配置文件位于/etc…...

82.二分查找
目录 什么是二分查找 一、左闭右闭写法[left,right] 代码演示: 二、左闭右开写法[left,right] 代码演示: 今天进行了二分查找的学习。 什么是二分查找 二分查找(Binary Search)是一种常用的搜索算法,也被称为折…...

线程是如何创建的
线程不是一个完全由内核实现的机制,它是由内核态和用户态合作完成的。pthread_create 不是一个系统调用,是 Glibc 库的一个函数,所以我们还要去 Glibc 里面去找线索。 首先处理的是线程的属性参数。例如前面写程序的时候,我们设置…...

owl_vit安装步骤
owl项目的clip目录与openai的clip重名了,import时容易找不到文件simple_tokenizer。 from clip import simple_tokenizer解决办法: 把clip项目下的simple_tokenizer.py拷贝到owl项目下的clip文件夹 cp simple_tokenizer.py /{project_dir}/scenic/scenic/projects…...

运行real.exe时出现NUM_METGRID_SOIL_LEVELS=0
本人在运行real.exe时,发现出现这样的报错: d01 2020-01-01_00:00:00 ---- ERROR: Mismatch between namelist and global attribute NUM_METGRID_SOIL_LEVELS NOTE: 2 namelist vs input data inconsistencies found. -------------- FATAL CALL…...

【数值计算方法】Gauss消元法及其Python/C实现
文章目录 一、基础理论1. 线性方程组2. Gauss消元法的详细步骤3. 注意事项 二、具体计算过程1. 用Gauss 消元法求A的LU分解,并由此求解方程组 Ax ba. 将A进行LU分解。b. 使用LU分解求解方程组Axb 三、代码实现1. Python代码实现2. C语言代码实现 Gauss消元法&#x…...

ins老被封禁?快来看看这些雷区你踩了没!
做外贸的小伙伴应该都运营或者接触过Instagram,但是忽视平台规则和操作不当很容易出现ins被封号的情况,今天就给大家介绍ins封禁原因,大家在运营过程中就可以很好避免了! Instagram 封禁原因 1.短时间内大量关注和点赞操作 为了封…...

《Effective Java》读书笔记(1-2章)
第一章 创建和销毁对象 1. 考虑用静态代替构造方法 想要获取一个类的实例,一种传统的方式是通过共有的构造器,当然还可以使用另一种技术:提供共有的静态工厂方法。 什么是静态工厂? public static Boolean valueOf(boolean b) …...

C++版split(‘_‘)函数
目录 1 使用stringstream2 使用双指针算法 1 使用stringstream #include <iostream> #include <sstream> #include <string> #include <vector>using namespace std;vector<string> split(string str, char separator) {vector<string> …...

Leaky singletons的一种使用场景
Leaky singletons的一种使用场景 文章目录 Leaky singletons的一种使用场景场景问题本质如何解决Leaky singletons 场景 最近遇到了这个问题,正好想记录下。 比如你有一段代码,如下(伪代码): static std::map<int…...

TensorFlow图像多标签分类实例
接下来,我们将从零开始讲解一个基于TensorFlow的图像多标签分类实例,这里以图片验证码为例进行讲解。 在我们访问某个网站的时候,经常会遇到图片验证码。图片验证码的主要目的是区分爬虫程序和人类,并将爬虫程序阻挡在外。 下面…...