- 博客(226)
- 收藏
- 关注
原创 对象,Class<?>,Klass 之间的关系,各自作用
维度对象 (Instance)Class对象 (Java层)Klass结构体 (JVM层)存储位置堆 (Heap)堆 (Heap)元空间 (Metaspace)谁在用程序员和JVM程序员(反射、getClass()JVM(方法调用、类型检查)存储内容具体的成员变量值类的名称、方法、字段的Java包装类的底层元数据、虚函数表、字段偏移量相互关联对象头指向KlassClass对象是Klass的镜像(Mirror)Klass的指向Class对象。
2026-07-25 10:02:02
159
原创 元空间是存放在堆中的吗?会OOM吗?触发GC机制是啥?
元空间OOM主要源于设置了MaxMetaspaceSize或物理内存不足。它的GC是‘阈值驱动’的,由MetaspaceSize触发,目标是回收‘死’的类元数据,且不依赖Full GC,这与堆GC‘空间耗尽驱动’、回收对象实例的机制有本质不同。
2026-07-25 09:31:33
190
原创 逃逸分析,什么对象可能在栈上分配
在逃逸分析中,对象逃逸状态分为三种,只有前两种逃逸状态含义能否栈上分配全局逃逸对象引用被静态字段存储,或作为返回值返回给调用者,或作为参数传给其他线程。生命周期不可控。❌ 不能参数逃逸对象作为参数传递给某个方法,但该对象本身并未在该方法外部被引用。这是分析中的一种特殊状态。✅ 有机会(需结合方法内联)无逃逸对象所有字段和方法访问都局限在创建它的方法内部,没有被任何外部持有引用。✅最高优先级触发优化最典型的栈上分配场景就是无逃逸状态。// 用户对象只在方法内部使用,没有任何外部引用。
2026-07-25 09:07:43
172
原创 线程池决策策略执行链路
addWorker(command, false) 返回 false → 线程数已达到 maximumPoolSize。workQueue.offer(command) 返回 false → 队列已满。ThreadPoolExecutor.execute() 核心源码。它是线程池的最后一道防线,用于保护系统不至于被任务压垮。
2026-07-19 10:38:12
17
原创 拒绝策略触发条件、默认的拒绝策略、自定义拒绝策略
拒绝策略是线程池的最后一道安全防线。当线程池无法处理新提交的任务时,拒绝策略决定了接下来会发生什么。特性抛异常✅ 是❌ 否❌ 否❌ 否任务丢失✅ 丢失❌ 不丢✅ 丢失✅ 可能丢失调用线程执行❌ 否✅ 是❌ 否❌ 否降低提交速度❌ 否✅ 是❌ 否❌ 否适合核心业务✅❌❌❌适合实时场景❌❌❌✅当内置策略不满足需求时,可以实现接口。可以,但要小心递归。建议加入重试次数限制。if (!// 重试拒绝策略是线程池的安全阀AbortPolicy → 快速失败,适合核心业务。
2026-07-19 10:23:24
51
原创 阻塞队列如何设置,要怎么监控,阻塞队列可以动态扩容吗
*** 支持动态调整容量的阻塞队列* 原理:内部持有两个队列,扩容时切换*//*** 动态扩容(需要谨慎使用,有性能开销)*/throw new IllegalArgumentException("容量必须大于0");try {// 创建新队列// 迁移已有元素// 切换引用log.info("队列容量从 {} 扩容到 {}, 当前元素数={}",// 所有方法委托给 delegate@Override@Override@Override。
2026-07-19 10:06:37
51
原创 最大线程数 是怎么考虑的
最大线程数 = 综合考虑外部资源、系统资源、业务需求后的平衡值= 不是计算出来的,而是权衡出来的= 需要压测验证,不能一次定终身设置一个合理范围 → 压测验证 → 监控调优 → 循环迭代。😊。
2026-07-19 09:58:16
41
原创 精确公式:Nthreads = Ncpu * (1 + WT/ST),怎么确定 WT/ST 比例
快速启动:先根据“经验判断法”设置一个值,比如。精准压测:通过压测工具,找到吞吐量的“拐点”,确定该业务的最佳线程数。日志埋点:在核心方法中添加耗时监控,收集线上的WT和ST数据,用于后续调优。动态调整:利用和方法,在不重启服务的情况下,对参数进行微调。
2026-07-19 09:44:33
184
原创 线程池-核心数 和 最大线程数 怎么设置
假设:8核CPU8个线程全部在计算 → CPU利用率100% ✅9个线程同时计算 → CPU时间片竞争,出现上下文切换 ❌但实测发现Ncpu + 1通常优于Ncpu页缺失(Page Fault):线程可能因访问内存而短暂阻塞,此时第N+1个线程可以接管CPUGC暂停:JVM垃圾回收时,某些线程会被暂停系统中断:操作系统中断处理会抢占CPUBrian Goetz(《Java并发编程实战》作者)的建议对于计算密集型的任务,线程数设置为CPU核心数 + 1通常能实现最优的利用率。总耗时 = 110ms。
2026-07-19 09:42:24
133
原创 AQS 和 synchronized导致cpu飙高原因一样吗
AQS 和导致 CPU 飙高的本质都是“多线程抢占同一资源时的管理开销”。但AQS 的痛点在“用户态自旋”(us 高),解决思路是减少 CAS 重试(如改用 LongAdder 或减小锁粒度);synchronized 的痛点在“内核态调度”(sy 高),解决思路是缩短锁持有时间,避免操作系统频繁挂起和唤醒线程。如果你现在手边有jstack日志,我可以帮你精准判断是哪种锁导致的 CPU 问题,并给出针对性的代码优化建议。😊。
2026-07-19 09:01:31
131
原创 如果没调 wait 和 notify,简单使用synchronized,线程在队列中是怎样的
的底层实现确实有Entry Set和Wait Set的概念,不过这是**重量级锁(Monitor锁)**在 JVM 底层(C++ 实现)的数据结构,更准确的名字是_EntryList和_WaitSet。你可以把它们看作是 JVM 为了管理等待锁的线程,而在底层维护的两个“线程休息室”。
2026-07-19 08:48:33
133
原创 java线程状态-blocked状态场景
因为 notify() 被调用时,唤醒线程B可能还持有锁(或者有其他线程持有锁)。wait() 的设计原则是:被唤醒后必须重新获得锁才能继续执行。休息区的人(Wait Set)必须先被叫号(notify),才能去排队(Entry Set),然后才能买票。与等待的区别:BLOCKED是被动的,它在等待一个排他锁;Wait Set 中的线程不能直接参与锁竞争,它们必须先被移到 Entry Set,才能参与争抢。关键点:Wait Set 的线程处于"休眠"状态,它们甚至不参与锁的调度,直到被显式唤醒。
2026-07-19 08:45:51
182
原创 synchronized 锁释放时的“竞争“
锁释放时的"竞争",是指所有等待线程(包括新来的)在锁对象上的_owner字段执行原子CAS操作**。由于多核CPU并行执行CAS,由硬件仲裁谁先成功,整个过程是非公平的,成功者获取锁,失败者继续阻塞等待下一次释放。**
2026-07-18 19:30:45
53
原创 AQS 锁导致cpu飙高原因和synchronized 是一样的吗
AQS 和导致 CPU 飙高的本质都是“多线程抢占同一资源时的管理开销”。但AQS 的痛点在“用户态自旋”(us 高),解决思路是减少 CAS 重试(如改用 LongAdder 或减小锁粒度);synchronized 的痛点在“内核态调度”(sy 高),解决思路是缩短锁持有时间,避免操作系统频繁挂起和唤醒线程。
2026-07-18 19:29:33
47
原创 数据库慢查询 为什么会导致CPU飙高
数据库慢查询导致CPU飙高,本质上是"慢查询消耗了数据库的CPU",同时"应用线程在等待慢查询的过程中大量堆积,引发频繁的上下文切换,消耗了应用服务器的CPU",形成双向夹击。最终,应用端和数据库端的CPU都被拖垮,系统进入雪崩状态。如果你能贴出topvmstat或的输出,我可以帮你精确定位是哪条SQL在作恶。😊。
2026-07-18 19:14:54
104
原创 cpu飙高的原因有哪些,什么思路去排查
CPU飙高不用慌,三步排查记心上:第一步,top看进程,确认Java是元凶;第二步,top -Hp看线程,找到吃CPU的凶;第三步,jstack转栈帧,定位代码看行踪。GC高用jstat看,锁竞争jstack多采样;火焰图用Arthas,内存泄漏jmap查。
2026-07-18 19:10:51
130
原创 频繁GC 为什么会导致CPU飙高
频繁 GC 导致 CPU 飙高的本质是:内存分配速度 > 垃圾回收速度,导致 GC 操作(主要是对象遍历和并发扫描)从低频“保洁”变为高频“战斗”,大量本应属于业务逻辑的计算资源被强制用于内存巡查。排查建议用观察 GC 间隔(如果间隔<1秒,CPU必高)。用查看堆中哪些类实例最多,找出是什么对象在“撑爆” Eden 区。考虑增大年轻代(-Xmn)或调整 G1 的,降低 GC 触发频率。贴一下的输出,准确判断是Young GC还是Full GC在吃CPU。😊GCT是GC Time。
2026-07-18 18:55:55
242
原创 SATB写屏障和增量更新写屏障区别
SATB(G1):管你后来有没有人引用你,只要你被快照记录过曾经有人引用你,我就先留着(保旧增量更新(CMS):我不管以前谁引用过你,只管从现在开始谁新引用你,谁新引用你我才管(追新SATB用内存空间(保留浮动垃圾)换准确性(不漏标);增量更新用算法复杂度(小心处理并发变化)换内存效率(少浮动垃圾)。G1最终胜出,因为漏标导致的Full GC比浮动垃圾可怕得多。
2026-07-18 18:05:12
142
原创 写屏障是个啥
写屏障就是JVM在"修改对象字段"这个动作前后,自动插入的一小段"拦截代码",就像你每次往仓库搬货时,门口的保安都要登记一下。│ 写屏障 = JVM在字段赋值指令前后插入的"钩子"代码 ││ ││ 目的:保证并发GC时,引用变更不会导致"漏标" ││ ││ G1的写屏障做两件事: ││ 1. SATB:修改前记录旧引用(防止漏标) ││ 2. 脏卡标记:记录跨Region引用(加速Remembered Set) ││ ││ 代价:每次赋值操作都多执行几行代码 → 性能略有下降 │。
2026-07-18 17:58:29
214
原创 G1-并发标记和最终标记算法
并发标记(Concurrent Marking):├── 算法:三色标记(Tri-color Marking)├── 支撑:SATB(Snapshot-At-The-Beginning)+ 写屏障├── 作用:遍历对象图,标记大部分存活对象└── 特点:与应用线程并发执行最终标记(Final Marking):├── 算法:SATB队列处理 + 三色标记收尾├── 支撑:SATB机制├── 作用:处理并发期间引用变化带来的遗留问题└── 特点:STW停顿,但非常短暂两者关系。
2026-07-18 17:53:33
254
原创 ()与{}
的通用场景,只有在箭头函数这种"函数体是单一表达式"的特殊场景下,两者才看起来像是能互换的(一个隐式返回、一个显式返回)。不是"多行代码块"的意思,它只是分组符号,作用是把里面的内容框成。它跟"多行"没关系,跟"是表达式还是语句块"有关系。是代码块(函数体),里面可以写任意条数的。这个理解不对,需要纠正一下。完全不是一回事,不能互换。
2026-07-13 15:02:37
218
原创 setState组件更新
在 StrictMode 下刷新会打印 2 次的原因是一样的:只要函数体被调用,里面所有同步代码都会执行,不只是 return 的 JSX。React 组件本质就是一个函数,每次这个组件要重新渲染,React 就会重新调用这个函数一遍,函数体里的代码(包括。setState -> 告诉React 状态变化 -> 需要重新渲染 -> 重新执行NameInput函数。写在组件函数体里,不是写在事件回调里。所以你点一次 checkbox,这也是为什么之前提到的。)都会重新执行一次。
2026-07-10 15:29:32
198
原创 函数Function详解
在 TypeScript 中,函数是,既可以作为参数传递,也可以作为返回值返回。TypeScript 为函数提供了支持,包括参数类型、返回值类型、可选参数、默认参数、剩余参数等。
2026-07-05 18:40:13
155
原创 类型分类、联合类型、交叉类型
Object类型表示所有非原始类型(即所有对象)。Object是所有引用类型的,类似于 Java 中的Object类。
2026-07-04 22:27:36
260
原创 类型与变量
就是告诉 TypeScript的语句。它就像是给变量、函数、对象等贴上的,让 TypeScript 编译器知道该如何理解和检查你的代码。type 可以用来定义别名,纯类型空间居民。
2026-07-04 16:55:36
226
原创 TS运行环境
TypeScript是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成。TypeScript通过TypeScript编译器或Babel转译为JavaScript代码,可运行在任何浏览器,任何操作系统浏览器是无法识别TS文件的,如果你在html比如<script>中引入ts话,浏览器报错。
2026-07-01 22:03:09
210
原创 py文件被初始化执行了2次
文件被引入后,正常当前文件只会被初始化一次,但是项目中发现初始化了2次,生成了2个workflow_registry对象。在pycharm中,将项目多个包设置为了source root。导入同一个文件的时候,路径名写的不一样,导致重复加载。Python 在 import 时先查它,命中就直接返回,没命中才去磁盘找文件并执行加载;,一旦被 import(或当成主脚本跑过),在。同一个文件,导入包路径。里就是一条普通记录,
2025-12-02 17:47:08
373
原创 核心组件之Agents
创建工具列表给agent。工具可以被定义为一个简单python函数或协程。可以被用来自定义tool 名称,描述,参数模式(argument schemas)以及其他属性@tool@tool如果你传一个空工具列表,那么agent就只包含一个llm节点,没有任何工具调用能力。
2025-12-01 19:08:20
143
原创 【无标题】
a car you rent,a car you pay to borrow. rental car.fee paid for using the highway.海威特。
2025-11-29 10:55:06
88
原创 LangChain 快速开始
安装LangChain 包LangChain 提供了上百个LLM的集成以及上千个其他集成。这些包都是独立的。比如pipuv。
2025-11-28 17:27:32
494
原创 LangChain 总览
LangChain 是最容易的方式去开发创建llm增强的agents和应用。仅仅只需要十几行代码就可以连接OpenAI, OpenAI, Anthropic, Google, and. LangChain 提供了一个预构建(pre-built)agent架构和模型集成,帮助你快速开始,并无缝地将大型语言模型(LLMs)整合到你的agents和应用程序中。如果想要快速创建agent和自动化应用,推荐使用LangChain。
2025-11-27 20:54:50
347
原创 SSE原理极简介绍
基于纯 HTTP/1.1 长连接,单向文本自动重连。id: 1\n以\n\n结尾表示一条消息结束。浏览器原生 API 叫,不支持 POST、不能自定义请求头;如需要可用模拟(俗称 Fetch-SSE)[1][6]。SSE(Server-Sent Events)协议帧里只有 4 个官方字段+ 1 个“注释”符号,全部可选;记住“4+1”即可。字段是否必填出现次数说明示例data通常要填可多条(会拼接)真正业务 payload,必须是字符串;JSON 先 stringifyid可选≤1。
2025-11-26 10:27:13
937
原创 LangGraph ReAct应用
创建一个简单的代理应用程序,该应用程序可以检查天气。该应用程序由一个代理(LLM)和工具组成。当我们与应用程序交互时,我们将首先调用代理(LLM)来决定是否应该使用工具。然后我们将运行一个循环请注意,这里我们将使用预构建的代理。LangGraph 的一大优势是你可以轻松创建自己的代理架构。因此,虽然从这里开始快速构建代理是不错的选择,但我们强烈建议你学习如何构建自己的代理,这样你就可以充分利用 LangGraph。
2025-11-20 17:23:37
178
原创 LangGraph的Send机制
LangGraph 的是一种“运行时动态分叉”能力:在「条件边」函数里返回一个列表,LangGraph 会为列表里的每个对象,并把私有状态作为该实例的输入,从而实现的 Map-Reduce 风格流程。
2025-11-20 14:10:22
261
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅