深入理解java虚拟机(JVM)------一篇过

2023-05-16

JVM——一篇过

发展史(不知道历史的程序员不是一个好秃子)

前身:Oak语言(91年开发消费性电子产品)

java me、java se、java ee

java me:移动终端java程序

java se:桌面级应用

java ee:企业家应用,包含了许多扩展包

JDK、jre、jvm

jvm:java虚拟机是运行java程序的,是实现跨平台

jre:包括jvm和java程序所需的核心类库,主要包含lang包

jdk:提供给开发人员使用的,包含了jre、java开发工具(javac.exe、jar.exe…)

年代史

95年,1.0发布—–>98年jdk1.2即时编译器——>04年jdk1.5(泛型、枚举等)——>08年sun被oracle收购74亿——>14年1.8lambda表达式,彻底移除永久代——>18Androidjava侵权赔88亿(相当公司白送的)

自动内存管理

在这里插入图片描述

程序计数器

线程私有的一个字节码行号指令器,当执行native方法时,为空(唯一一个不报空指针异常

栈(线程私有)

jvm栈

java方法调用时分配空间存储局部变量等,用完就释放

本地方法栈

执行native方法时分配空间存储变量

堆(线程共享)

存放对象实例(new 对象,静态对象,1.7加入了静态变量和常量池),也是GC管理的区域,也叫GC堆

方法区(线程共享)

存储class、常量、静态变量

jdk1.7时将字符串常量和静态变量移到堆中,jdk1.8废除方法区的概念,改用元空间来存储class

元空间

jdk1.8时出现用来代替方法区的

为什么要用元空间

传统的方法区是占用jvm的内存的,是有内存溢出的风险,但是元空间是占用本地内存,是由电脑的内存决定,所以空间很大,基本不会出现内存溢出的情况

运行时常量池

属于方法区,即在程序运行时将一些常量加载到池中,常用的一种是:String.intern()

直接内存(了解)

不是jvm运行数据区,默认和最大堆内存一样大,在jdk1.4时,引入NIO,NIO利用native方法堆外内存,可以通过DirectByteBuffer对象对直接内存操作,避免了java堆和native堆的来回复制,即Netty(基于NIO实现的)的零拷贝性质

对象的创建(new 对象)

直接上图:类加载后面会讲,别问我怎么设置对象头啥的,有的东西记住就行了,就像我tm抽你,你问为什么,不为什么,你只要知道你被打了就行

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

内存分配的两种方式

指针碰撞

假设堆内存左边是利用了的,右边是空闲的,中间有一个指针,分配内存时,将指针向右挪动对象内存大小,当使用Serial、ParNew收集器时(空间压缩整理)用这种内存分配方式

空闲列表

使用的内存和空闲的交错在一起,就需要维护一个列表,当分配内存时,将一个足够容纳对象大小的内存分配给它就行,当使用CMS(清除)收集器时用这种方式分配内存

后面会讲到垃圾收集器!!

对象内存布局

对象头

两部分:

  1. hashcode、GC分代年龄、锁的信息
  2. 堆向指向它的类型元数据的指针

数据部分

不仅包含了自己的数据,还包含了父类继承下来的字段信息

对齐填充(非必然存在)

HotSpot虚拟机要求对象大小是8字节的整数倍,不是的话就要通过对其填充来补全

对象的访问

  1. 句柄访问:通过句柄池找到对象指针,在通过指针找到对象

  2. 直接指针:直接通过对象的指针访问,快速效率高

理解不了?看下面例子

例如:你想找个老婆,你可以找媒婆帮你找一个,你也可以直接找一个,但是呢,结婚以后突然你老婆跑了,那你怎么办,在找一个呗,这时候找媒婆的优势就来了,省时省力,直接叫她在帮你找一个,但是你自己找的老婆呢,就又要自己辛辛苦苦去找

内存溢出(OOM)和内存泄露(ML)

内存泄露:无用对象(垃圾)的内存不释放,导致这部分回收不了,一直占着

内存溢出:在程序申请内存时,内存不够,出现的一种异常,内存泄露的后果就是内存溢出

垃圾收集和内存分配策略

垃圾回收

无用对象的回收叫垃圾回收,怎么判断是不是垃圾呢?

  1. 引用计数算法:对象添加引用计数器,每次有对象引用改对象时,就会+1,引用失效-1,计数为0时就是可以回收的,该算法看是简单,实际却需要很多额外处理,所以基本没有虚拟机用该算法
  2. 可达性分析:通过“GC Roots”作为根节点集,跟据引用链向下搜索,没有在引用链上的对象就是可回收对象

四大引用

  1. 强引用:Object o=new Object()这种,垃圾回收永远不会回收
  2. 软引用:java类中有一个SoftReference来实现软引用,在内存溢出之前会被回收
  3. 弱引用:java提供了WeakReference来实现,垃圾回收时就会回收掉该对象
  4. 虚引用:PhantomReference,唯一的目的是为了在该对象被回收时收到一个通知

回收过程

当判定一个对象是不可达时不会被马上回收掉的,必须经过连个阶段

  1. 不可达判断为true,第一次标记
  2. 对象是否执行了finalize方法,如果执行就代表已经被回收过了,如果没有就放入一个F-Queue,稍后会对queue中第二次标记,将标记两次的对象由一个线程优先级低的Finalizer线程去执行finalize方法回收对象

垃圾回收算法

标记清除算法

标记需要回收的对象后,统一回收

缺点:

  1. 执行效率不稳定,回收对象过多效率会降低
  2. 内存碎片化问题

标记复制算法

将对象回收后的存活对象复制到另一个等大的内存中,将原来的空间清理,在将两块空间对换,该算法多用于新生代回收算法

缺点:对空间的浪费

优点:解决了内存碎片化的问题,且新生代朝生夕灭,存活对象少,所以效率很高

标记整理算法

将对象回收后的空隙进行整理,多用于老年代的回收算法

缺点:整理式对象移动必须全程暂停用户应用程序,否则导致指针混乱,就像你数鸭子,鸭子一直跑,着你怎么数

优点:由于老年代的对象都是老干部,都是经过风吹雨打存活下来的,所以比较少对象会被回收,所以整理的代价还是比较小的

HotSpot算法实现细节

根节点枚举

根节点枚举必须暂停所以线程,可达性分析时,并不需要1个不漏的遍历,HotSpot利用了一个OopMap数据结构来存放对象引用,在特定位置记录栈和寄存器的引用

安全点

OopMap在特定位置记录时的特点位置就是安全点,所以线程执行到安全点后就开始垃圾收集

安全区域

在某一段区域的任意地方进行垃圾收集都时安全的

垃圾回收器

Serial收集器

早期的**“单线程”(新生和老年垃圾回收时暂停所以工作)**新生代垃圾回收器,对于运行在客户端模式的虚拟机时一个不错的选择

ParNew收集器

Serial的多线程(新生代多线程)版本,但是垃圾回收时,依旧需要暂停所以工作

Parallel Scavenge收集器

是一个重吞吐量的新生代多线程垃圾回收器

Serial Old收集器

Serial的老年代版本收集器,也是一个单线程

Parallel Old收集器

多线程Parallel Scavenge的老年代版本,不能和CMS配合

CMS收集器

以最短回收时间停顿的收集器,内存足够时,使用标记清除,不足时用标记整理

过程
  1. 初始标记(停止工作)
  2. 并发标记
  3. 重新标记(停止工作)
  4. 并发清除

G1收集器

面向服务端的全堆垃圾收集器,哪块存放的垃圾最多,回收效益最大,着就是Mixed GC模式

ZGC收集器

利用染色体指针来实现低延迟垃圾回收器

染色体指针:一种可扩展的存储结构用来记录更多与对象标记、重定向过程相关的数据

实战

  1. 对象优先分配在Eden:大多数情况下,对象都是分配在Eden新生代的
  2. 大对象直接进入老年代:大对象的垃圾回收很耗费资源,所以要避免过多大对象进入新生代
  3. 长期存活的对象将进入老年代(默认是年龄15)
  4. 动态对象年龄判定:相同年龄数量大于总数一半,这些相同年龄就应该直接进入老年代,否则可能会导致新生代回收效率低下
  5. 空间分配担保:发生minor GC之前,会去检查老年代可用空间是否大于新生代总对象空间,大于是安全的,根据概率赌不会使老年代空间不够而发生full GC

类加载机制

在这里插入图片描述

特例:解析过程可能会在初始化之后(动态绑定或晚期绑定)

6种情况必须初始化

  1. new 、getstatic、putstatic、、invokestatic指令时
  2. new实例化对象时
    1. 定义该数组类,不会初始化
  3. 对类型进行反射时
  4. 父类为初始化时,先初始化父类
    1. 调用父类的静态变量,子类不会初始化
    2. 使用常量池的变量,不会初始化
  5. 1.8加入default接口实现类初始化,接口也要初始化
  6. 方法句柄没有初始化时

加载

  1. 利用非数组的类的全限类名来获取二进制字节流
  2. 将字节流转换到方法区(1.8之后的元空间)中
  3. 生成一个class

数组类加载:数组类不通过类加载器加载创建,而是直接在内存动态构造

验证

保证class文件字节流符合约束,且不会对jvm造成危害

  1. 文件格式验证
  2. 元数据验证
  3. 字节码验证
  4. 符号引用验证

准备

static变量初始化并赋原始值(int赋0),而真正的赋值是在构造器中赋值

解析

将常量池的符号引用替换为直接引用

初始化

执行类构造器()方法的过程

类加载器

一个类的全限类名二进制字节流放到jvm外部,让程序直接去获取需要的类

双亲委派机制

每次都会将类给父类加载器去尝试加载,加载不了才会给子类加载

顺序:启动类加载器——>扩展类加载器——>应用程序类加载器——–>自定义类加载器(必须继承抽象类ClassLoader)

img

被破坏过3次

  1. jdk1.2才提出双亲委派机制,所以1.2之前的并不符合
  2. 线程上下文加载器:父类加载器去请求子类加载器完成类加载
  3. 模块化热部署时会破坏

程序编译和代码优化

编译器

  • 前端编译器:javac编译器将.java编译成.class文件
  • 即时编译器:C1、C2,Graal编译器将字节码变成本地机器码
  • 提前编译器:ATO编译器把程序编译成与目标机器指令想关的二进制代码

优化

前端编译器(前端优化):对代码基本无优化,但是对编码效率和使用等有比较多的优化手段(语法糖等)

即时编译器(后端优化):几乎大代码有话都放到该阶段完成,运行期优化可使一些可移植class也享受到优化

编译过程

1个准备、3个处理过程

  1. 准备过程:初始化插入注解处理器
  2. 解析填充符号表过程
    • 语法、词法、填充符号表
  3. 插入式注解处理器处理注解过程
  4. 分析与字节码生成过程
    • 静态信息检查、动态运行检查、解语法糖、字节码生成

泛型

Java的实现方式是类型擦除式泛型

类型擦除

  1. 运行期原始泛型派生对原始类型的继承关系
  2. 编译器直接抹除(例:ArrayList —–>ArrayList)
既然抹除了泛型,为什么反射还能取得参数化类型?

答:虽然在字节码抹除了泛型,但是在元数据还是保留了泛型信息

后端编译和优化

即时编译器

作用:将字节码中的**热点代码(多次调用的方法、多次调用的循环体)**编译成本地机器码

  • C1编译器:又叫客户端编译器
  • C2编译器:又叫服务端编译器
  • Graal编译器:JDK10出现来替换C2的编译器,现在不清楚

热点探索

  1. 采样:周期性检查栈顶,经常在栈顶的方法(J9)
  2. 计数器:每次调用就+1(HotSpot)

热度衰减

一定时间内,调用次数不够即时编译器门槛,就会在垃圾回收时随便计数器减半

提前编译器

2分支作用:

  1. 本质时给即时编译器做缓存加速
  2. 静态提前编译(在系统空闲时编译)

即时编译器对提前编译器的优势

  1. 性能分析制导优化:热点代码集中优化和分配更好的资源
  2. 激进预测性优化:性能监控支持概率预测优化
  3. 链接时优化:动态链接

编译器优化技术(前沿技术)

对中间代码或机器码进行代码优化,而不是对源码优化

方法内联

将方法体替换方法调用,增加了代码量,但是减少了地址引用

逃逸分析

对象逃出原本的作用域(return 对象)

公共子表达式消除

表达式计算过,且过程变量不变,则直接使用

数组边界检查消除

1.编译期完成边界检查 2.隐式异常处理

一些普通的优化

常量迭代、算数聚合、符号合并……

Graal编译器

展望替换HotSpot成为一款高效编译、高质量输出、支持即时编译和提前编译、支持不同虚拟机的编译器、继承HotSpot的高质量优化技术

java内存模型(JMM)与线程

硬件效率与一致性

处理器的熟虑与内存的速度根本不是一个等级,这样就限制了我们的效率,所以引入了高速缓存的存储交互(但是带来了缓存一致性问题)

JMM

目的:定义程序中各种变量的访问规则

在这里插入图片描述

怎么解决缓存一致性问题:

在这里插入图片描述

volatile

  1. 可见性:解决内存屏障带来的不可见问题,每次读取之前会去主存中查看最新的值,判断变量是否过期,过期的话就会从主存读取最新的值,每次写操作时将缓存行数据立即写入主存,且让其他其他CPU缓存了改变量的地址无效(简单来说就是每次使用前向主内存主刷新
  2. 禁止指令重排:在并发的情况下,JVM的指令重排优化可能会对变量的操作产生影响,这是就需要禁止指令重排来避免

内存屏障

由于编译器的优化和缓存的使用,导致对内存的写入操作不能及时的反应出来,也就是说当完成对内存的写入操作之后,读取出来的可能是旧的内容

long、double(64位)的非原子协议

对于64位数据类型,虚拟机会将它的读写操作分为3次32位的操作,这样就不能保证操作的原子性了

例如:两个线程同时去对long或double进行读取和修改,可能即得不到原来的值,也得不到修改后的值

实际开发:除非你明确知道该类型变量有线程竞争,否则没有必要去加volatile关键字

线程实现(了解)

Thread的所以关键方法都声明位Native,即本地方法

三种实现方式

  1. 内核线程实现(1:1)一般不会直接使用内核线程
  2. 用户线程(1:n):我们常用的Thread线程的建立即与他操作都在用户态完成,不需要内核帮助,程序设计好就不需要切换导内核态,高速低消耗
  3. 混合实现:内有轻量级线程作为桥梁,对状态的切换等提高很多,也可以支持大规模的用户线程并发

状态转换

  • new 创建未使用
  • Runable:
    • Running:运行时
    • Ready:准备运行,等待CPU分配时间片,阻塞状态获取导锁后就进入准备运行状态
  • Waiting:无限等待被其他线程唤醒,在等待池中
  • Timed Waiting:休眠,等时间过来就会苏醒,典型的sleep方法(sleep期间不会释放对象的锁)
  • 阻塞:等待获取一个排他锁,等待线程被唤醒后就加入阻塞状态

线程安全和锁优化

线程安全

当一个线程操作变量时,其他的线程不会对该变量的操作造成影响

  1. 不可变变量:String 、枚举、final修饰的变量、java.lang.Number的部分子类(Long、Double…)
  2. 绝对线程安全:不管什么环境,都是线程安全的
  3. 相对线程安全:大部分线程安全集合类(Vector、hashMap….)等

锁优化

JDK5—->JDK1.6加入了很多的锁优化手段:适应性性自旋、锁消除、锁膨胀、轻量级锁、偏向锁

自旋锁

默认开启,在获取锁失败后,会自旋重试来获取锁

锁消除

对被检测导明确不会存在锁竞争的锁进行锁消除来提高运行效率,锁消除的根据还是逃逸分析技术(前面讲过了)

锁粗化

一串零碎的锁操作对同一个对象,加锁的范围扩展导整个操作序列的外部

轻量级锁

对象头(mark word)记录一些的对象的非数据信息,里面就包含了锁标志等,轻量级锁锁升级后会变成重量级锁

偏向锁

将mark word内的偏向模式设为1,标志位设位01,则是偏向锁状态,锁竞争会锁升级位轻量级锁

具体的锁和并发可看JUC

final修饰的变量、java.lang.Number的部分子类(Long、Double…)
2. 绝对线程安全:不管什么环境,都是线程安全的
3. 相对线程安全:大部分线程安全集合类(Vector、hashMap….)等

锁优化

JDK5—->JDK1.6加入了很多的锁优化手段:适应性性自旋、锁消除、锁膨胀、轻量级锁、偏向锁

自旋锁

默认开启,在获取锁失败后,会自旋重试来获取锁

锁消除

对被检测导明确不会存在锁竞争的锁进行锁消除来提高运行效率,锁消除的根据还是逃逸分析技术(前面讲过了)

锁粗化

一串零碎的锁操作对同一个对象,加锁的范围扩展导整个操作序列的外部

轻量级锁

对象头(mark word)记录一些的对象的非数据信息,里面就包含了锁标志等,轻量级锁锁升级后会变成重量级锁

偏向锁

将mark word内的偏向模式设为1,标志位设位01,则是偏向锁状态,锁竞争会锁升级位轻量级锁

具体的锁和并发可看JUC

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解java虚拟机(JVM)------一篇过 的相关文章

  • 如何使用 Apache POI API 将图像添加到 pptx 中添加的图像占位符?

    我已经预定义了带有文本和图像占位符的 pptx 模板 我如何从模板访问和修改这些占位符 我可以使用 POI pptx API 直接将图像和文本添加到幻灯片中 但如何将其添加到模板的占位符中 请参阅链接以了解如何添加占位符来创建固定模板 ht
  • Java - 为什么不允许 Enum 作为注释成员?

    It says 原始 String Class an Enum 另一个注释 上述任何一个的数组 只有这些类型才是合法的 Annotation 成员 为什么泛型 Enum 不能成为 Annotation 的成员 例如 Retention Re
  • 插入最大日期(独立于数据库)

    在我的本地设置中 我使用一个简单的 H2 数据库 托管 解决方案将有另一个 类似但不相同 数据库 我需要将最大可能日期插入到日期时间列中 我尝试使用 Instant MAX 但是 这会导致列中出现 169104626 12 11 20 08
  • 这个函数(for循环)空间复杂度是O(1)还是O(n)?

    public void check 10 for string i list Integer a hashtable get i if a gt 10 hashtable remove i 这是 O 1 还是 O n 我猜测 O n 但不是
  • Java:如何从转义的 URL 获取文件?

    我收到了一个定位本地文件的 URL 事实上我收到的 URL 不在我的控制范围内 URL 按照 RFC2396 中的定义进行有效转义 如何将其转换为 Java File 对象 有趣的是 URL getFile 方法返回一个字符串 而不是文件
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • JAVA - Xuggler - 组合 MP3 音频文件和 MP4 电影时播放视频

    使用 JAVA 和 Xuggler 以下代码组合 MP3 音频文件和 MP4 电影文件并输出组合的 mp4 文件 我希望在合并音频和视频文件时应自动播放输出视频文件 String inputVideoFilePath in mp4 Stri
  • java中如何连接字符串

    这是我的字符串连接代码 StringSecret java public class StringSecret public static void main String args String s new String abc s co
  • 如何在不超过最大值的情况下增加变量?

    我正在为学校开发一个简单的视频游戏程序 我创建了一个方法 如果调用该方法 玩家将获得 15 点生命值 我必须将生命值保持在最大值 100 并且由于我目前的编程能力有限 我正在做这样的事情 public void getHealed if h
  • 使用 AES SecretKey 的 Java KeyStore setEntry()

    我目前正在 Java 中开发一个密钥处理类 特别是使用 KeyStore 我正在尝试使用 AES 实例生成 SecretKey 然后使用 setEntry 方法将其放入 KeyStore 中 我已经包含了代码的相关部分 The KS Obj
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 如何模拟从抽象类继承的受保护子类方法?

    如何使用 Mockito 或 PowerMock 模拟由子类实现但从抽象超类继承的受保护方法 换句话说 我想在模拟 doSomethingElse 的同时测试 doSomething 方法 抽象超类 public abstract clas
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • 具有 java XSLT 扩展的数组

    我正在尝试使用 java 在 XSLT 扩展中使用数组 我收到以下错误 Caused by java lang ClassCastException org apache xpath objects XObject cannot be ca
  • Java 中的“Lambdifying”scala 函数

    使用Java和Apache Spark 已用Scala重写 面对旧的API方法 org apache spark rdd JdbcRDD构造函数 其参数为 AbstractFunction1 abstract class AbstractF
  • 在游戏视图下添加 admob

    我一直试图将 admob 放在我的游戏视图下 这是我的代码 public class HoodStarGame extends AndroidApplication Override public void onCreate Bundle
  • 如何在selenium服务器上提供自定义功能?

    我知道可以通过某种方法获得一些硒功能 其中之一如下 driver getCapabilities getBrowserName 它返回浏览器名称的值 但如果它指的是一个可用的方法 如果我没有误解的话 这似乎与自定义功能有关 就像我的意思是
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi

随机推荐

  • go 编写tcp和udp服务端和客户端

    TCP协议 TCP IP Transmission Control Protocol Internet Protocol 即传输控制协议 网间协议 xff0c 是一种面向连接 xff08 连接导向 xff09 的 可靠的 基于字节流的传输层
  • tcp黏包问题

    服务端代码如下 xff1a span class token keyword package span main span class token keyword import span span class token punctuati
  • go sync.Pool 深入

    new函数的调用时机和pool的内存释放规则 以下代码调用了四次Get函数 xff0c 但是并不是每次都会new 第一次 xff0c 是a 61 pool Get byte xff0c 首次Get xff0c 在pool的private私有
  • 【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)

    深入理解扩散模型 xff1a Diffusion Models 引言扩散模型的原理扩散过程反向过程优化目标 模型设计代码实现Stable Diffusion DALL E Imagen背后共同的套路Stable DiffusionDALL
  • gin 框架原理

    Gin的路由原理 Gin的路由基于Trie树和压缩字典树算法 xff0c 什么是Trie树 xff1f 其实很好理解 xff0c 看下图 xff1a 单词at xff0c bee xff0c ben xff0c bt xff0c q组成的T
  • PowerDesigner导入sql脚本

    1 依次点击File gt Reverse Engineer gt Database 2 弹出弹窗对模型进行命名 xff0c 同时在DBMS下拉选择框中需要选择自己对应的数据库类型 xff0c 点击确定 新的弹窗 xff0c 选中Using
  • Gin路由算法模拟

    概述 Gin的路由算法是采用压缩字典树实现的 xff0c 基数树 xff08 Radix Tree xff09 又称为PAT位树 xff08 Patricia Trie or crit bit tree xff09 xff0c 是一种更节省
  • 使用gomail发送邮件

    概述 为了实现一个邮件验证码功能 xff0c 特意了解了一下go如何发送邮件 本来以为会很麻烦 xff0c 没想到其实很简单 工具类 实现的工具类如下 xff1a span class token keyword package span
  • redis实现消息队列的几种方式及其优劣

    概述 常用的消息队列有 xff0c rabbitMq kafka RocketMq ActiveMq等 这些消息队列需要独立安装部署 xff0c 作为一个中间件来提供服务 xff0c 虽然有着高性能 高可靠的优点 xff0c 但是额外部署这
  • linux系统或者windows WSL安装redis最新版本

    概述 因为windows的最新版本redis已经在16年就停止更新了 xff0c 目前最新的版本只到redis3 xff0c 很多redis新增的特性都无法使用 例如redis5的stream xff0c windows版本就没有 这篇文章
  • 在面对一些亿级流量场景,消息队列届的排头兵kafka是如何保证高性能的呢?

    在面对一些亿级流量场景 xff0c 消息队列届的大哥kafka是如何保证高性能的呢 xff1f Kafka Reactor模型架构 Kafka客户端和服务端通信采取的是NIO的reactor模式 xff0c 它是一种事件驱动模式 react
  • Redis是如何实现高性能的?

    Redis作为应对高并发场景的利器 xff0c 它是如何实现高性能的呢 xff1f IO多路复用 传统对于并发情况 xff0c 假如一个进程不行 xff0c 那搞多个进程不就可以同时处理多个客户端连接了么 xff1f 多进程是可以解决一些并
  • go更新最新版本

    最近go1 18出了泛型 xff0c 趁着周末有时间 xff0c 赶不及要尝尝鲜呢 那如何更新我本地go到最新版本到1 18呢 1 下载安装包 https go dev dl 2 执行安装 点击打开安装程序 xff0c 点击next 选择卸
  • idea、goland泛型语法报错解决|go1.18泛型初体验

    go在1 18正式推出了泛型 xff0c 你是否和博主一样好奇其语法呢 xff1f 快啊来看看吧 1 版本更新 amp 插件更新 go如何更新到最新版本 xff0c 可以查看https www hengyumo cn momoblog de
  • 【统计学习】5分钟了解假设检验中的第一类错误和第二类错误

    5分钟了解假设检验中的第一类错误和第二类错误 假设检验假设检验 xff1a 可能性Type I 第一类错误Type II 第二类错误举个例子总结参考资料 在假设检验中 xff0c 第一类错误和第二类错误是两种可能的错误类型 第一类错误 xf
  • godis 运行原生redis命令

    我们可能会遇到需要运行的某些命令在godis中不存在的情况 xff0c 这个时候我们可以使用其原生的方式运行命令 xff0c 为了方便使用 xff0c 封装了一个方法 xff0c 用于简化这个过程 需要注意的是 xff0c 执行命令的返回结
  • Beego项目打包部署到Linux服务器

    1 打包beego项目 xff0c 项目目录下执行 bee pack be GOOS 61 linux 2 将压缩包传到服务器gopath目录下 xff0c 进行解压 xff0c tar zxvf filename tar gz 3 给执行
  • Python 获取目录及子目录下所有文件 (不包括文件夹),极简

    其实就是想记一下这个华丽的大推导式 xff0c 一行解决 xff1a span class token comment path 是要遍历的根目录 xff0c 34 34 是当前目录 span path span class token o
  • K8S问题-kubectl exec命令无法进入pod环境,处于卡住状态

    问题现象 xff1a kubectl exec it podname n ns bash 命令超时 定位思路 xff1a bash 换成sh检查是否正常 不正常 检查node是否正常 正常 试一下问题pod所在的node上的别的pod是否也
  • 深入理解java虚拟机(JVM)------一篇过

    JVM 一篇过 发展史 xff08 不知道历史的程序员不是一个好秃子 xff09 前身 xff1a Oak语言 xff08 91年开发消费性电子产品 xff09 java me java se java ee java me xff1a 移