每天60秒读懂世界
1、两部门联合发布高温健康风险预警提示:山东、河南、安徽、陕西、湖北等9省份部分地区风险极高;2、国铁集团:暑运启动以来,全国累计发送旅客突破7亿人次,同比增长4.1%;3、2025年暑期档电影总票房破100亿,《南京照相馆》《浪浪山小妖怪》《长安的荔枝》分列前三位;4、广电总局:改进电视剧集数与季播剧播出间隔管理;鼓励支持优秀微短剧进入电视播出……
欢迎访问本站,本站记录博主日常编程遇到的问题,知识,惊奇软件等。如有问题还请留言
1、两部门联合发布高温健康风险预警提示:山东、河南、安徽、陕西、湖北等9省份部分地区风险极高;2、国铁集团:暑运启动以来,全国累计发送旅客突破7亿人次,同比增长4.1%;3、2025年暑期档电影总票房破100亿,《南京照相馆》《浪浪山小妖怪》《长安的荔枝》分列前三位;4、广电总局:改进电视剧集数与季播剧播出间隔管理;鼓励支持优秀微短剧进入电视播出……
jvm的槽为啥是32位,64jvm也是32位呢1. 什么是 jvm 的“槽”(slot)在 java 虚拟机中,局部变量表(Local Variable Table) 是方法栈帧的一部分。它由一组 slot(槽位) 组成,每个 slot 的基本单位是 32 位(4字节)。slot 可以存放:int, float, reference, retu……
jvm的垃圾回收是如何暂停所有线程的1. 为什么需要暂停线程?GC 需要对堆内存中的对象做可达性分析(reachability analysis),判断哪些对象是垃圾。如果应用线程(Mutator Threads)还在继续运行,就可能:在 GC 标记过程中修改对象引用,导致结果不一致;在对象回收时还在访问已被标记回收的对象。因此,GC 必须让所……
1、纪念中国人民抗日战争暨世界反法西斯战争胜利80周年大会第二次综合演练顺利完成;2、首届世界人形机器人运动会落幕,世界人形机器人运动联合会宣告成立;第二届将于2026年8月在北京举办;3、成都世运会闭幕:产生233枚金牌,中国队获36金17银11铜位居金牌、奖牌榜首位;4、内蒙古乌拉特后旗突发山洪:已致野外露营人员10人遇难2人失联,1人获救,目前有……
DDD 并不是凭空冒出来的,它确实是从传统的业务驱动拆分路径里,把那些零散的、依赖个人经验的做法提炼成了一套可复用、可传授的方法论,然后加上统一的术语体系,让团队协作、跨团队建模、系统演进更可控。换句话说传统业务拆分:靠经验 → 每个架构师可能都有自己的套路 → 结果好坏取决于人DDD:把这些套路标准化 → 给它命名(限界上下文、聚合、值对象…)→……
1、2025暑期档电影总票房已突破96亿,其中《南京照相馆》票房超25亿领跑;2、前7月全国新建商品房销售面积近5.16亿平方米,同比下降4%;新建商品房销售额约49566亿元,下降6.5%;3、官方通报“女司机亮证逼迫让路事件”后续处理结果:“亮证女”丈夫被注销行政执法证,6人被问责;4、山东荣成一载11人面包车坠海致6死2失联,3人获救,事发时为凌……
🧠 为什么 mesi 协议并不足以保证 java 中的“可见性”语义?1. mesi 是硬件层级的缓存一致性,volatile 是语言层级的可见性保证mesi 主要解决“同一物理地址在多核缓存中的副本一致性问题”;根据mesi,CPU某核(假设CPU0)的缓存行(包含变量x)是M S 或E的时候,如果总线嗅探到了变量x被其其他核(比如CPU1)执行了……
HashMap1. Hash 冲突后的数据结构变化(jdk8 之后的优化)在 jdk8 之前,HashMap 发生冲突后使用的是链表结构,导致在极端情况下时间复杂度退化为 O(n)。jdk8 开始引入红黑树结构优化:当某个桶(链表)中的元素个数超过 TREEIFY_THRESHOLD = 8 且容量超过 MIN_TREEIFY_CAPACITY ……
1. 容器应用创建在 Kubernetes 中,容器应用的创建不仅仅依赖于 docker run 命令,还可以通过 Kubernetes 的资源对象进行创建和管理。Kubernetes 提供了类似 Docker 容器的功能,但与 Docker 容器不同的是,Kubernetes 会在集群中进行调度和管理。下面我会详细介绍一些 Docker 和 Kubern……
java-10-新特性与旧版功能的变更java-11-新特性与旧版功能的变更java-12-新特性与旧版功能的变更……
🧭 整体结构总览层级技术视角控制权体现提供能力对上层支撑1. 计算机硬件CPU、存储、总线线性执行+跳转程序计数器、堆栈、跳转指令支持有序与跳跃控制2. 计算机组成原理存储程序原理、函数调用栈跳转+调用+返回+中断函数、递归、上下文切换抽象为过程式语言3. 操作系统用户态、内核态、线程调度控制权分时复……
java的thread.sleep方法是会响应中断的,cpu会使用定时器,定时器到时会触发中断让cpu调度这个线程,但是我不明白java中将线程设置中断,为什么sleep可以响应中断指令,是怎么做到的?java 的 Thread.sleep() 为什么可以响应 interrupt()?在 java 中,Thread.sleep() 会放弃 CPU 执行权……
新的字符串和文件方法在 Java 11 中,我们已经获得了一些新的 String 方法,以及Files.readString() 和 writeString() 方法。而在 Java 12,jdk 开发人员对这两个类进一步扩展,新增了一些实用的方法。String.indent() —— 方便的字符串缩进在 Java 12 之前,如果我们想给字符串添加缩……
Lambda 参数的局部变量语法jdk 增强提案 323允许在隐式类型 lambda 表达式的中使用“var”关键字。先来看 显式类型 的 Lambda 表达式。在下面的代码中,参数 l 和 s 的类型 被明确声明(List<String> 和 String):(List<String> l, String s) -> l……
局部变量类型推断("var")从 Java 10 开始,我们可以使用关键字 var 来声明局部变量(局部意味着在方法内部)。例如,以下定义是允许的:var i = 10;var hello = "Hello world!";var list = List.of(1, 2, 3, 4, 5);var httpC……
最近项目想上直播和拍卖业务,自身流量也是比较大,想问下目前业界 ws 方案下是不是更推荐 netty 或者有没有其他可以参考的方案呢?直播推流这快准备用阿里云的,直播上会用到 ws 的也就是评论,拍卖可能就是出价和评论。1. 使用 netty 的建议sagaxu:不要直接用 netty,建议使用 Vert.x 或者 Quarkus。wxw752:我……
简化版代码:package com.mystic.ycc.blog.test;import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import j……
线程和同步性能线程和硬件💡 CPU 增加线程并不能使应用程序性能倍增任务被提交到一个队列(可能不止一个队列),然后一定数量的线程会从队列中取出任务并执行它们线程池的大小对实现最佳性能至关重要在某些情况下,过大的线程池会导致性能急剧下降线程池大小应根据系统负载、CPU 和 I/O 任务比例来决定线程数超出 CPU 数量可能会降低吞吐量💡 C……
jdk 8 到 jdk 23 的 语法糖(语言特性) 和 垃圾回收(GC)优化语法糖(语言特性)演进从 Lambda 表达式到模式匹配,java 逐步引入更简洁的语法和现代编程范式。jdk 8(2014)Lambda 表达式:List list = Arrays.asList("a", "b", "c");list.forEach(s ->……
关于 jdk 不同版本对 指令集支持1. jdk 8(2014年)指令集支持:基线指令集:主要针对 SSE2/SSE4.1/AVX1(如 Intel Haswell 之前的处理器)。不支持AVX-512(Skylake 及之后的新指令集)。AES-NI 深度优化(仅部分支持)。向量化运算优化有限。适用场景:传统企业应用,无需高……
您已发表16条评论。
日期时间 | 金币 | 类别 | 状态 | 描述 |
---|---|---|---|---|
2021-06-17 09:42:41 | 10 | 充值 | accepted | comment_posted_12 |
2024-08-07 03:15:01 | 10 | 充值 | accepted | comment_posted_40 |
2025-08-17 08:17:32 | 10 | 充值 | accepted | comment_posted_168 |
111
2025-08-17 16:17:32 发表在 DDD[g=qiang]
2024-09-26 17:03:39 发表在 JVM GC 的安全点与安全区域1
2024-08-07 11:15:01 发表在 ngrok内网穿透因为OutOfMemoryError是可以catch的。catch之后吞掉的话程序还能试着继续运行。例如说以前见过的一个案例是:一个Java服务器端应用,有段代码没写对导致有一个线程在疯狂创建大数组对象——直到OOM。这个线程注册的uncaught exception handler捕获到了这个异常,记录了日志,然后就把这个异常吞掉了。这样还能继续正常跑下去是因为:只是一个创建很大的数组对象的请求失败了而已,而出错的那个方法由于异常处理已经被退出了,程序的其它部分并没有受影响。
2023-10-05 17:15:25 发表在 JAVA发生OOM后还能运行么?作者:RednaxelaFX链接:https://www.zhihu.com/question/35777031/answer/64575683来源:知乎太长不读(TL;DR)版定性分析:对于解释器来说,解释器开销主要来自解释器循环(fetch-decode/dispatch-execute循环)中的fetch与decode/dispatch,反而真正用于执行程序逻辑的execute部分并不是大头。每条指令都要经历一轮FDX循环。因而减少指令条数可以导致F与D的开销减少,于是就提升了解释器速度。基于栈与基于寄存器的指令集,用在解释器里,笼统说有以下对比:从源码生成代码的难度:基于栈 < 基于寄存器,不过差别不是特别大表示同样程序逻辑的代码大小(code size):基于栈 < 基于寄存器表示同样程序逻辑的指令条数(instruction count):基于栈 > 基于寄存器简易实现中数据移动次数(data movement count):基于栈 > 基于寄存器;不过值得一提的是实现时通过栈顶缓存(top-of-stack caching)可以大幅降低基于栈的解释器的数据移动开销,可以让这部分开销跟基于寄存器的在同等水平。请参考另一个回答:寄存器分配问题? - RednaxelaFX 的回答采用同等优化程度的解释器速度:基于栈 < 基于寄存器交由同等优化程度的JIT编译器编译后生成的代码速度:基于栈 === 基于寄存器因而,笼统说可以有以下结论:要追求尽量实现简单:选择基于栈传输代码的大小尽量小:选择基于栈纯解释执行的解释器的速度:选择基于寄存器带有JIT编译器的执行引擎的速度:随便,两者一样;对简易JIT编译器而言基于栈的指令集可能反而更便于生成更快的代码,而对比较优化的JIT编译器而言输入是基于栈还是基于寄存器都无所谓,经过parse之后就变得完全一样了。===========================================JVM的选择JVM当初设计的时候非常重视代码传输和存储的开销,因为假定的应用场景是诸如手持设备(PDA)、机顶盒之类的嵌入式应用,所以要代码尽量小;外加基于栈的实现更简单(无论是在源码编译器的一侧还是在虚拟机的一侧),而且主要设计者James Gosling的个人经验上也对这种做法非常熟悉(例如他之前实现过PostScript的虚拟机,也是基于栈的指令集),所以就选择了基于栈。回头看,这个决定也还算OK,可惜的是基于栈的设计并没有让Java的代码传输大小减小多少。这是因为:Java代码是以Class文件为单位来传输与存储的。Java从设计之初就非要支持分离编译(separate compilation)与按需动态类加载(on-demand dynamic class loading),导致Java的Class文件必须独立的(self-contained)——每个Class文件必须自己携带自己的常量池,其主要信息是字符串与若干其它常量的值,以及用于符号链接的符号引用信息(symbolic reference)。如果大家关注过Class文件的内容的话,会知道其实通常Class文件里表示程序逻辑的代码部分——“字节码”——只占Class文件大小的小头;而大头都被常量池占了。而且多个Class文件的常量池内容之间常常有重叠,所以当程序涉及多个Class文件时,就容易有冗余信息,不利于减少传输/存储代码的大小。大家或许还记得Google在Google I/O 2008的Dalvik VM Internals演讲里,Dan得意的介绍到Dalvik的Dex格式在未压缩的情况下都比压缩了的JAR文件还小么?(下面数据引用自演示稿第22页)common system libraries (U) 21445320 — 100% (J) 10662048 — 50% (D) 10311972 — 48%web browser app (U) 470312 — 100% (J) 232065 — 49% (D) 209248 — 44% alarm clock app (U) 119200 — 100% (J) 61658 — 52% (D) 53020 — 44%(U) uncompressed jar file(J) compressed jar file(D) uncompressed dex fileDan准确的介绍了Dex体积更小的原因:一个Dex相当于一个或多个JAR包,里面可以包含多个Class文件对应的内容。一个Dex文件里的所有Class都共享同一个常量池,因而不会像Class文件那样在多个常量池之间有冗余。这样Dex文件就等同于在元数据层面上对JAR文件做了压缩,所以前者比后者更小。但是很明显后来有不少群众不明就里,以为Dalvik的Dex文件更小是跟基于寄存器的选择相关的——其实正好相反,在字节码部分,Dalvik的字节码其实比JVM的字节码更大。只要仔细读了同一个演示稿就会看到(第37页)The Register Machine30% fewer instructions35% fewer code units35% *more* bytes in the instruction streambut we get to consume two at a time而其实Java世界里早就发现了这个问题,并且有一个传输/存储格式跟Dex文件应用了类似的压缩思路:pack200格式。它也是把JAR包里的所有Class文件的常量池汇总为一个,以此压缩掉其中的冗余。以pack200格式打包的Java应用就不会比用Dex格式打包大了。之前在Oracle的HotSpot JVM组工作时,跟同事们讨论一些与此相关的话题,大家的共识是如果JVM的指令集是在20年后的今天设计的话,很有可能也会跟现在的潮流相似,基于寄存器。不过就算保持现在这样用基于栈的指令集也挺好。目前Class文件/JAR文件的真正让大家头疼的问题并不是基于栈还是基于寄存器的设计,而是别的地方,例如:Class文件方面:各种人为的大小限制都跟不上时代了,例如每个方法的字节码最多65535字节;要生成StackMapTable太闹心;常量池的组织方式不便于直接从文件映射到内存然后高效执行;可以有更高效的组织方式。JAR文件方面:如前文提的,多个Class文件之间的常量池冗余;缺少带有强语义的描述模块的信息;等等…一切都有待未来版本的Java继续改进。===========================================Lua的选择官方版Lua的设计可以从经典文章 The Implementation of Lua 5.0 一窥究竟。它提到:For ten years (since 1993, when Lua was first released), Lua used a stack-based virtual machine, in various incarnations. Since 2003, with the release of Lua 5.0, Lua uses a register-based virtual machine.也就是说Lua 5.0之前的Lua其实是用基于栈的指令集,到5.0才改为用基于寄存器的。接下来:Register-based code avoids several “push” and “pop” instructions that stack-based code needs to move values around the stack. Those instructions are particularly expensive in Lua, because they involve the copy of a tagged value, as discussed in Section 3. So, the register architecture both avoids excessive copying of values and reduces the total number of instructions per function. Davis et al. [6] argue in defense of register-based virtual machines and provide hard data on the improvement of Java bytecode. Some authors also defend register-based virtual machines based on their suitability for on-the-fly compilation (see [24], for instance).所以Lua 5.0开始改为选用基于寄存器的指令集设计,主要是出于 (1) 减少数据移动次数,降低由数据移动带来的拷贝开销,和 (2) 减少虚拟指令条数 这两点考虑。从纯解释器的角度看,这两点考虑是非常合理的。不过如果官方版Lua有JIT编译器的话,它就没必要这么做了——基于栈和基于寄存器的指令集只要经过合理的编译,得到的结果会是一模一样的。至于LuaJIT,LuaJIT 1.x的字节码设计源于Lua 5.1.x系列,因而也是基于寄存器的;LuaJIT 2.x系列的字节码虽然重新设计了,但应该还是受到之前设计的影响而继续采用了基于寄存器的设计。像Mike Pall那种想榨干一切性能的思路,即便有优化的JIT编译器,也还是想让解释器尽量快的心情也是可以理解的。
2023-09-26 11:47:32 发表在 栈式虚拟机和寄存器式虚拟机?寄存器线程私有的[g=zhemo]
2023-09-22 09:37:48 发表在 volatile单核的情况下能保证线程安全么volatile:从最终[汇编语言]从面来看,volatile使得每次将i进行了修改之后,增加了一个内存屏障lock addl $0x0,(%rsp)保证修改的值必须刷新到[主内存]才能进行[内存屏障]后续的指令操作。但是内存屏障之前的指令并不是原子的代码例子[code] public static volatile int race = 0; public static void increase() { race++; }[字节码]public static void increase(); Code: 0: getstatic #2 // Field race:I 3: [iconst_1] 4: iadd 5: [putstatic] #2 // Field race:I 8: return[/code]指令“lock; addl $0,0(%%esp)”表示加锁,把0加到栈顶的[内存单元],该指令操作本身无意义,但这些指令起到内存屏障的作用,让前面的指令执行完成。具有XMM2特征的CPU已有内存屏障指令,就直接使用该指令volatile方式的[i++],总共是四个步骤:i++实际为load、Increment、store、Memory Barriers 四个操作。内存屏障是[线程安全]的,但是内存屏障之前的指令并不是.在某一时刻线程1将i的值load取出来,放置到[cpu缓存]中,然后再将此值放置到[寄存器]()A中,然后A中的值自增1(寄存器A中保存的是[中间值],没有直接修改i,因此其他线程并不会获取到这个自增1的值)。如果在此时[线程2]也执行同样的操作,获取值i==10,自增1变为11,然后马上刷入主内存。此时由于线程2修改了i的值,实时的线程1中的i==10的值缓存失效,重新从主内存中读取,变为11。接下来[线程1]恢复。将自增过后的A[寄存器值]11赋值给cpu缓存i。这样就出现了线程安全问题。[克里斯泡]既然他从主存中读取了最新的11那什么不会把这个值放到寄存器中加一呢,而是把之前的值直接写会主存?[千帆]这个涉及到MESI缓存一致性协议,为了保证不同缓存的一致性,一旦某个线程执行了修改(Modify)操作,会立刻使其他层级的缓存失效(invaild),然后立刻从主存中读取最新值~协议就是这样规定的---[明明]寄存器里面的11已经是用缓存中的10自加后的结果了,然后才是缓存中的10失效,重新从内存读取11,这个重新读取的11则会进行下一次自加。不知道我这样的理解是否正确。---[明明]不会自加的,自加这个操作已经完成了,只是cpu缓存的值会更新---[明明]我知道你的疑问在哪里。作者的意思是,一个线程会有3个操作内存:1主存2缓存3寄存器 只有从缓存读到寄存器这一步才会检查10是否无效。一但读入寄存器,就不会进行检查了,即时已经被无效。---突然就懂了!---[千帆]你好,我问下,这里说的会立刻使其他层级的缓存失效(invaild),然后立刻从主存中读取最新值,然后会再进行+1计算,写入主存吗,还是只是读取内存的值,不再进行计算了呢---[田林轩]立刻从主存中读取最新值不再进行计算了!---[黄花小伙子]cpu执行编译后的代码/指令也是自上而下执行有个固定顺序,线程1进行自增完成后发现别的线程已经修改且刷新了值,线程1这时候只能从主存中获取最新值,然后继续后面的回写操作,不可能获取最新值后把这段自增的代码再跑一边的,因为这样从程序逻辑上会有更大问题,比如100个线程一起自增,线程1一直很倒霉,它每次自增完后都发现其他线程刚更新了数据,它就只能重新获取最新数据然后重新跑,在其他线程停止自增之前它永远都结束不了运行---[田林轩]寄存器的值应该也会更新的,不过不影响,如果i已经被一个线程读到栈顶的话(栈是线程私有的),i在寄存器中的值发生变化也无所谓,因为自增操作是在栈上执行完然后再写回寄存器到缓存到内存。栈上的操作不会被改变。
2023-09-15 09:43:16 发表在 volatile为什么不能保证原子性?就是我写的
2023-08-25 17:48:25 发表在 【性能测试篇】你现在用的SIMPLEDATEFORMAT类性能最差!嘿嘿嘿[g=chi]
2023-01-17 16:07:47 发表在 下面哪谢书是你看过的啥破玩意
2023-01-17 11:25:33 发表在 下面哪谢书是你看过的1
2023-01-09 09:30:43 发表在 链路追踪实现原理( ఠൠఠ )ノ
✗棒棒的✗
✗棒棒的✗ ✗棒棒的✗ ✗棒棒的✗ ✗棒棒的✗
✗笑哭了✗ ✗棒棒的✗