Go内存管理
内存管理
文章目录
- 内存管理
- 何为内存?
- 内存为什么需要管理?
- 内存管理的方式
- 操作系统存储模型
- 操作系统是怎么管理内存的?
- 虚拟内存与物理内存
- 认识虚拟内存
- 分页管理
- Golang 内存模型
- TCMalloc核心概念
- go内存管理核心概念
- GO内存分配
- GO 内存逃逸机制
- 一、内存逃逸的本质
- 二、逃逸分析的核心策略
- 三、常见逃逸场景解析
- 1. **指针逃逸**
- 2. **栈空间不足逃逸**
- 3. **动态类型逃逸**
- 4. **闭包引用逃逸**
- 5. **接口方法调用**
- 6. **切片动态扩容**
- 四、逃逸分析的影响
- 五、如何检测逃逸
- GO 内存泄漏
- 内存泄漏定义
- 常见涉及语言
- 常见场景
- 内存泄漏检测与解决
- 总的来说
- **工具使用**
何为内存?
- 来源:基于内存条
- 作用:程序逻辑临时使用时用的变量、全局变量、静态库、函数跳转地址、执行代码、临时开辟的结构体对象
内存为什么需要管理?
- 内存中存储的数据越来越多,导致物理内存不足[每个程序索要的内存是程序的极限内存](需要提高内存的利用率和合理分配性)
对于一些语言如:go、java、python,为了能让开发者更关注程序本身的逻辑,提供了一套针对自身程序的内存管理模式:虚拟内存
内存管理的方式
操作系统存储模型
观察上图,我们可以从中捕捉到的关键词是:
- 多级模型
- 动态切换
操作系统是怎么管理内存的?
存在问题:
- 物理内存无法最大化使用
- 程序逻辑内存使用空间独立
- 物理内存不足
解决手段:
- 读时共享
- 写时复制
- 内存不足时部分磁盘虚拟化
虚拟内存与物理内存
虚拟内存:一连串连续的逻辑内存,逻辑内存地址映射真实物理内存地址
物理内存:真实基于内存条的实际内存。
认识虚拟内存
虚拟内存的作用:
- 在用户与硬件间添加中间代理层(没有什么是加一个中间层解决不了的)
- 优化用户体验(进程感知到获得的内存空间是“连续”的)
- “放大”可用内存(虚拟内存可以由物理内存+磁盘补足,并根据冷热动态置换,用户无感知)
分页管理
操作系统中通常会将虚拟内存和物理内存切割成固定的尺寸,于虚拟内存
而言叫作“页”
,于物理内存
而言叫作“帧”
,原因及要点如下:
- 提高内存空间利用(以页为粒度后,消灭了不稳定的外部碎片,取而代之的是相对可控的内部碎片)
- 提高内外存交换效率(更细的粒度带来了更高的灵活度)
- 与虚拟内存机制呼应,便于建立虚拟地址->物理地址的映射关系(聚合映射关系的数据结构,称为页表)
- linux 页/帧的大小固定,为 4KB(这实际是由实践推动的经验值,太粗会增加碎片率,太细会增加分配频率影响效率)
内部碎片:比如:页内的内存浪费(7字节可能分配8字节的空间;内存对齐补齐的内存;内存池的预留内存)
外部碎片:比如:内存分配对象大小、释放时机(不可控)[需要考虑物理内存的连续性,比如:剩余两块内存,4KB和2KB的内存块。现在需要6KB的连续物理空间,不存在则分配内存失败]
但是,此时如果存在分页管理,外部的空闲内存块以页帧为单位管理。只要页帧足够,就可以进行内存分配,不需要连续的内存块。这就实现了彻底消除外部碎片的效果。
Golang 内存模型
首先,golang中借用操作系统的存储模型和TCMalloc。理解 TCMalloc 可以有助于理解 go内存管理。虽然之后 Go的内存管理 与TCMalloc不一致地方在不断扩大,但其主要思想、原理和概念都是和TCMalloc一致的…
- 借鉴了操作系统的多级缓存和分页管理的机制
- 借鉴了TCMalloc。TCMalloc是 Google 开发的一款高效内存分配器,TCMalloc 通过独特设计减少锁竞争,提升多线程环境下内存分配和释放效率 。
TCMalloc核心概念
- Page
操作系统对内存管理以页为单位,TCMalloc也是这样,只不过TCMalloc里的Page大小与操作系统里的大小并不一定相等,而是倍数关系。《TCMalloc解密》里称x64下Page大小是8KB。
- Span
一组连续的Page被称为Span,比如可以有2个页大小的Span,也可以有16页大小的Span,Span比Page高一个层级,是为了方便管理一定大小的内存区域,Span是TCMalloc中内存管理的基本单位。
- ThreadCache
ThreadCache是每个线程各自的Cache,一个Cache包含多个空闲内存块链表,每个链表连接的都是内存块,同一个链表上内存块的大小是相同的,也可以说按内存块大小,给内存块分了个类,这样可以根据申请的内存大小,快速从合适的链表选择空闲内存块。由于每个线程有自己的ThreadCache,所以ThreadCache访问是无锁的。
- CentralCache
CentralCache是所有线程共享的缓存,也是保存的空闲内存块链表,链表的数量与ThreadCache中链表数量相同,当ThreadCache的内存块不足时,可以从CentralCache获取内存块;当ThreadCache内存块过多时,可以放回CentralCache。由于CentralCache是共享的,所以它的访问是要加锁的。
- PageHeap
PageHeap是对堆内存的抽象,PageHeap存的也是若干链表,链表保存的是Span。当CentralCache的内存不足时,会从PageHeap获取空闲的内存Span,然后把1个Span拆成若干内存块,添加到对应大小的链表中并分配内存;当CentralCache的内存过多时,会把空闲的内存块放回PageHeap中。
如下图所示,分别是1页Page的Span链表,2页Page的Span链表等,最后是large span set,这个是用来保存中大对象的。毫无疑问,PageHeap也是要加锁的。
前文提到了小、中、大对象,Go内存管理中也有类似的概念,我们看一眼TCMalloc的定义:
- 小对象大小:0~256KB
- 中对象大小:257~1MB
- 大对象大小:>1MB
小对象的分配流程:ThreadCache -> CentralCache -> HeapPage,大部分时候,ThreadCache缓存都是足够的,不需要去访问CentralCache和HeapPage,无系统调用配合无锁分配,分配效率是非常高的。
中对象分配流程:直接在PageHeap中选择适当的大小即可,128 Page的Span所保存的最大内存就是1MB。
大对象分配流程:从large span set选择合适数量的页面组成span,用来存储数据。
go内存管理核心概念
-
free
(空闲内存管理相关) -
scav
(垃圾回收相关 ) -
arenas
区域是堆内存的具体分区,用于存放实际数据 -
Page
与TCMalloc中的Page相同,x64架构下1个Page的大小是8KB。上图的最下方,1个浅蓝色的长方形代表1个Page。
- Span(即mspan)
Span与TCMalloc中的Span相同,Span是内存管理的基本单位,代码中为mspan,一组连续的Page组成1个Span,所以上图一组连续的浅蓝色长方形代表的是一组Page组成的1个Span,另外,1个淡紫色长方形为1个Span。
- mcache
mcache与TCMalloc中的ThreadCache类似,mcache保存的是各种大小的Span,并按Span class分类,小对象直接从mcache分配内存,它起到了缓存的作用,并且可以无锁访问。但是mcache与ThreadCache也有不同点,TCMalloc中是每个线程1个ThreadCache,Go中是每个P拥有1个mcache。因为在Go程序中,当前最多有GOMAXPROCS个线程在运行,所以最多需要GOMAXPROCS个mcache就可以保证各线程对mcache的无锁访问,线程的运行又是与P绑定的,把mcache交给P刚刚好。
- mcentral
mcentral与TCMalloc中的CentralCache类似,是所有线程共享的缓存,需要加锁访问。它按Span级别对Span分类,然后串联成链表,当mcache的某个级别Span的内存被分配光时,它会向mcentral申请1个当前级别的Span。
但是mcentral与CentralCache也有不同点,CentralCache是每个级别的Span有1个链表,mcentral是每个级别的Span有2个链表,这和mcentral申请内存有关,有指针(contains pointers)的 Span 链表[存储包含 Go 指针的对象,这些 Span 需要参与垃圾回收标记过程。]和无指针(no pointers)的 Span 链表[存储纯值类型(如整数、浮点数、字符串等),这些 Span 在垃圾回收时可以直接跳过扫描,提高 GC 效率。].
- mheap
mheap与TCMalloc中的PageHeap类似,它是堆内存的抽象,把从OS申请出的内存页组织成Span,并保存起来。当mcentral的Span不够用时会向mheap申请内存,而mheap的Span不够用时会向OS申请内存。mheap向OS的内存申请是按页来的,然后把申请来的内存页生成Span组织起来,同样也是需要加锁访问的。
但是mheap与PageHeap也有不同点:mheap把Span组织成了树结构,而不是链表,并且还是2棵树,然后把Span分配到heapArena进行管理,它包含地址映射和span是否包含指针等位图,这样做的主要原因是为了更高效的利用内存:分配、回收和再利用。
总体来说:
mheap
是全局内存池,管理所有堆内存,并包含所有mcentral
实例。(只有一个)mcentral
按span-class(对象大小规格 + 是否含指针)维护 mspan 链表:- 每个
span-class
对应一个mcentral
,负责为该规格分配 / 回收mspan
。 - 向
mheap
申请大块内存(mspan
),切割为小块对象后,供mcache
缓存。 - 数量和 span-class 相关(1:1)
- 每个
mcache
是每个P
独占的本地缓存,包含各 span-class 对应的 mspan 链表:- 从
mcentral
获取特定span-class
的mspan
,避免频繁加锁访问全局资源。 - 直接为
Goroutine
分配对象,提升分配效率。 - 数量和P相关(1:1)
- 从
span-class
定义mspan
管理的对象大小范围和属性(如是否含指针),是内存分层管理的核心规格。- span-class对应的是小对象(大对象是单独独占一个span)
- 67种
它们通过分层协作,实现了高效的并发内存分配与管理。
- object size:代码里简称size,指申请内存的对象大小。
- size class:代码里简称class,它是size的级别,相当于把size归类到一定大小的区间段,比如size[1,8]属于size class 1,size(8,16]属于size class 2。
- span class:指span的级别,但span class的大小与span的大小并没有正比关系。span class主要用来和size class做对应,1个size class对应2个span class,2个span class的span大小相同,只是功能不同,1个用来存放包含指针的对象,一个用来存放不包含指针的对象,不包含指针对象的Span就无需GC扫描了。
- num of page:代码里简称npage,代表Page的数量,其实就是Span包含的页数,用来分配内存。
GO内存分配
按对象大小分配:
0~16B,不包含指针的对象 Tiny分配(span-class)
0~16B,包含指针的对象 正常分配(span-class)
16B~32KB 正常分配(span-class)
32KB ~ ∞ 大对象分配(mspan独占)
分配调用流程:
GO 内存逃逸机制
一、内存逃逸的本质
Go 语言中的内存逃逸是编译器优化技术,核心目标是自动决定变量应该分配在栈上还是堆上。其触发条件是变量的生命周期超出当前函数的作用域。这种机制允许 Go 开发者无需手动管理内存(如 C++ 中的 new/delete),同时保证程序的内存安全。
二、逃逸分析的核心策略
逃逸分析的决策逻辑可总结为:
-
外部引用原则
-
如果变量在函数外部存在引用(如返回指针、赋值给全局变量等),必须分配在堆上
-
示例:
func escapeToHeap() *int {x := 10 // x逃逸到堆return &x }
-
-
栈优先原则
-
如果变量仅在函数内部使用(无外部引用),优先分配在栈上
-
示例:
func stayOnStack() int {x := 10 // x分配在栈上return x }
-
-
栈容量限制
- 即使无外部引用,如果变量占用内存过大(超过栈空间限制),仍会分配到堆上
- 具体阈值与 Go 版本和平台有关(通常为几 KB 到几十 KB)
-
动态类型约束
-
当变量类型为
interface{}
时(动态类型),由于编译期无法确定实际类型大小,必须逃逸到堆 -
示例:
func dynamicTypeEscape() interface{} {x := struct{}{} // x逃逸到堆return x }
-
-
引用类型发生二次间接引用极大可能逃逸
引用类型:func()函数类型;interface{}接口类型;slice;map;channel;*(指针类型);
二次间接引用场景举例:func(
[]string
) ; map[string]interface{}
; slice[*int
] ; chan[]stirng
…其中标中的类型为将要逃逸的类型
三、常见逃逸场景解析
1. 指针逃逸
-
场景:函数返回局部变量的指针
-
原因:指针在函数外部被引用,生命周期超出函数范围
-
示例:
func createPtr() *int {x := 10 // x逃逸到堆return &x }
2. 栈空间不足逃逸
-
场景:创建大型数组或结构体
-
原因:栈空间有限(通常为几 MB),大型对象会导致栈溢出
-
示例:
func largeArray() {arr := [1000000]int{} // 可能逃逸到堆 }
3. 动态类型逃逸
-
场景:将对象赋值给 interface {} 类型
-
原因:interface {} 的底层实现需要指针和类型信息,编译期无法确定实际大小
-
示例:
func printAny(x interface{}) {fmt.Println(x) }func callPrintAny() {num := 42 // num逃逸到堆printAny(num) }
4. 闭包引用逃逸
-
场景:闭包引用外部函数的局部变量
-
原因:闭包可能在外部函数返回后执行,需要保证变量生命周期
-
示例:
func closureEscape() func() int {x := 10 // x逃逸到堆return func() int {return x} }
5. 接口方法调用
-
场景:通过接口调用方法
-
原因:接口调用需要动态分派,可能导致接收者逃逸
-
示例:
type Printer interface {Print() }type Data struct {Value int }func (d Data) Print() {fmt.Println(d.Value) }func interfaceEscape(p Printer) {p.Print() // 可能导致p的接收者逃逸 }
6. 切片动态扩容
-
场景:append 操作导致切片容量超过预分配值
-
原因:扩容时需要分配新的底层数组,并复制数据
-
示例:
func sliceEscape() {s := make([]int, 0, 1)s = append(s, 1) // 第一次append可能不逃逸s = append(s, 2) // 第二次append可能导致扩容,底层数组逃逸到堆 }
四、逃逸分析的影响
- 性能影响
- 堆分配比栈分配慢(涉及 GC 开销)
- 过度逃逸会导致 GC 压力增大,降低程序性能
- 内存布局
- 栈上对象随函数返回自动回收
- 堆上对象需要 GC 周期回收,可能导致内存碎片
- 代码优化建议
- 尽量避免返回局部变量的指针
- 减少使用 interface {} 类型
- 预估切片容量,减少动态扩容
- 优先使用值接收者而非指针接收者(除非需要修改原对象)
五、如何检测逃逸
-
编译命令
go build -gcflags="-m -m" main.go
-m
选项显示逃逸分析信息- 多个
-m
会输出更详细的分析
-
典型输出示例
./main.go:10:9: &x escapes to heap: ./main.go:10:9: flow: ~r0 = &x: ./main.go:10:9: from &x (address-of) at ./main.go:11:9 ./main.go:10:9: from return &x (return) at ./main.go:11:2
通过理解和利用逃逸分析机制,Go 开发者可以写出更高效、更符合语言特性的代码,避免不必要的堆分配和 GC 压力。
GO 内存泄漏
内存泄漏定义
内存泄漏指程序中已分配的内存,在使用完毕后因未被正确释放或无法被回收,导致这部分内存资源持续占用,无法重新分配利用。随着时间推移,泄漏的内存不断累积,最终会耗尽系统资源,引发程序性能严重下降、响应迟缓,甚至导致程序崩溃或系统不稳定。在 Go 语言中,尽管拥有自动垃圾回收(GC)机制,但由于代码逻辑缺陷,仍可能产生内存泄漏问题 。
常见涉及语言
- 手动内存管理语言(如 C/C++):开发者需手动使用
malloc
/free
、new
/delete
等函数分配和释放内存。一旦遗漏释放操作,或者释放逻辑错误(如重复释放、释放时机不当),就会造成内存泄漏。例如在 C 语言中,若动态分配内存后忘记调用free
函数:
int* ptr = (int*)malloc(sizeof(int));
// 使用ptr
// 未调用free(ptr),导致内存泄漏
- 自动 GC 语言(如 Go、Java):这类语言依赖自动垃圾回收机制来管理内存,理论上无需开发者手动释放内存。然而,若代码中存在对象的无效引用、循环引用、资源未关闭等情况,也会导致内存无法被 GC 回收,从而引发内存泄漏。例如在 Go 语言中,即使有 GC,错误的代码逻辑仍会导致泄漏。
常见场景
- 对象长期引用但不使用
- 原理:程序中存在对象被长期持有引用,但后续不再使用该对象,导致 GC 无法回收其占用的内存。例如,将对象放入全局变量或静态集合中,却不再对其进行任何操作。
- 示例:
var globalList []*MyObjectfunc createObject() {obj := &MyObject{}globalList = append(globalList, obj)// 后续不再使用obj,但globalList持续引用,导致obj无法被回收
}
- 循环引用
- 原理:多个对象之间形成环形引用关系,导致每个对象都被其他对象引用,即使这些对象实际已不再被程序使用,GC 也无法识别并回收它们。虽然 Go 语言的 GC 采用三色标记法,一定程度上能处理循环引用,但复杂的数据结构仍可能出现问题。
- 示例:
type Node struct {data intnext *Node
}func createCycle() {a := &Node{}b := &Node{}a.next = bb.next = a// a和b形成循环引用,若后续无其他引用,仍可能导致内存泄漏
}
- goroutine 永久性阻塞
- 原理:启动的 goroutine 因死锁、等待永远不会满足的条件(如无缓冲通道接收操作但无发送操作)等原因被永久阻塞,且 goroutine 内部持有的资源无法释放,随着大量阻塞 goroutine 的创建,会消耗大量内存资源。
- 示例:
func blockedGoroutine() {ch := make(chan int)go func() {<-ch // 等待接收,但无其他协程向ch发送数据,导致该协程永久阻塞}()
}
- 资源未关闭
- 原理:在操作文件、网络连接、数据库连接等资源时,若未调用对应的关闭方法释放资源,资源相关的内存及系统句柄等会持续占用,无法被回收。
- 示例:
func readFileWithoutClose() {file, err := os.Open("test.txt")if err != nil {return}// 未调用file.Close()关闭文件,可能导致内存泄漏及文件句柄资源占用data := make([]byte, 1024)file.Read(data)
}
- 定时器未清理
- 原理:创建的定时器(
time.Timer
、time.Ticker
)若不再使用却未停止或清理,会持续占用内存及系统资源,导致泄漏。 - 示例:
- 原理:创建的定时器(
func leakTimer() {ticker := time.NewTicker(time.Second)go func() {for {<-ticker.C// 业务逻辑,但未停止ticker,若该协程持续运行,会导致泄漏}}()
}
内存泄漏检测与解决
总的来说
- 定期内存分析:使用
pprof
定期监控内存使用情况,对比不同时间点的内存快照。 - goroutine 数量监控:统计活跃 goroutine 数量,异常增长可能意味着存在阻塞。
- 资源管理原则:
- 打开资源后立即使用
defer
关闭 - 使用
context.Context
控制 goroutine 生命周期 - 优先使用无状态或短生命周期的对象
- 打开资源后立即使用
- 测试覆盖:编写压力测试,模拟长时间运行场景,检测内存增长趋势。
通过结合工具检测和代码优化,可以有效避免 Go 程序中的内存泄漏问题。
工具使用
- pprof 工具
作用:分析内存分配和使用情况,定位内存泄漏点。
示例代码(存在内存泄漏):
package mainimport ("net/http"_ "net/http/pprof"
)var data []bytefunc leakHandler(w http.ResponseWriter, r *http.Request) {// 每次请求都会追加1MB数据,但从不清理data = append(data, make([]byte, 1024*1024)...)w.Write([]byte("Memory leaked!"))
}func main() {http.HandleFunc("/leak", leakHandler)// 启动pprof服务http.ListenAndServe(":6060", nil)
}
检测步骤:
-
启动程序:
go run main.go
-
触发泄漏:多次访问
http://localhost:6060/leak
-
采集内存快照:
go tool pprof http://localhost:6060/debug/pprof/heap
-
分析结果:
(pprof) top 10 # 查看内存占用最高的10个函数 (pprof) list leakHandler # 查看leakHandler函数的内存分配情况 (pprof) web # 可视化分析(需安装graphviz)
关键指标:
inuse_space
:当前堆上占用的内存alloc_space
:程序运行期间累计分配的内存- 若两者差距持续增大,可能存在泄漏。
- go tool trace
作用:可视化程序运行过程,发现阻塞的 goroutine。
示例代码(存在 goroutine 阻塞):
package mainimport ("os""runtime/trace"
)func main() {f, _ := os.Create("trace.out")defer f.Close()trace.Start(f)defer trace.Stop()ch := make(chan int)go func() {<-ch // 无发送操作,永久阻塞}()select {} // 主协程阻塞
}
检测步骤:
-
生成跟踪文件:
go run main.go
-
分析跟踪文件:
go tool trace trace.out
-
在浏览器中查看:
- 选择
Goroutine analysis
查看阻塞的 goroutine - 选择
Network blocking profile
查看网络阻塞情况
- 选择
相关文章:
Go内存管理
内存管理 文章目录 内存管理何为内存?内存为什么需要管理?内存管理的方式操作系统存储模型操作系统是怎么管理内存的?虚拟内存与物理内存认识虚拟内存分页管理 Golang 内存模型TCMalloc核心概念go内存管理核心概念GO内存分配GO 内存逃逸机制一…...
解决软件连接RabbitMQ突发System.IO.IOException: 无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接异常
一、问题描述 系统再运行时,突然出现 System.Exception: [RabbitMQ.Send Error] RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Library, code541, text“Unexpected…...
基于局部显著位置感知的异常掩码合成方法在CT图像肺部疾病异常检测与病变定位中的应用|文献速递-深度学习医疗AI最新文献
Title 题目 Local salient location-aware anomaly mask synthesis for pulmonary disease anomaly detection and lesion localization in CT images 基于局部显著位置感知的异常掩码合成方法在CT图像肺部疾病异常检测与病变定位中的应用 01 文献速递介绍 肺部疾病是全球发…...
【cursor疑惑】cursor续杯后使用agent对话时,提示“需要pro或商业订阅的用户才能使用“
背景 cursor的pro会员体验过期了,想再次体验deepseek、Claude等agent对话提示:“免费版本不可以使用agent对话功能(英文忘记截图了,大意是这样)”。 处理方法 Step-1:再次续杯cursor的pro会员14天体验 详情,见:【c…...
2022年下半年信息系统项目管理师——综合知识真题及答案(3)
2022年下半年信息系统项目管理师 ——综合知识真题及答案(3) 零、时光宝盒 (https://blog.csdn.net/weixin_69553582 逆境清醒) 此文是我2025-05-19回复头条上某作者文章时的评论记录,原作者的文章是写那些被有组织…...
华为云Flexus+DeepSeek征文|基于华为云Flexus云服务的云服务器单机部署Dify-LLM应用开发平台
目录 一、前言 二、华为云Flexus云服务优势 三、华为云Flexus一键部署Dify 3.1 选择模板 3.2 参数配置 3.3 资源栈设置 3.4 配置确认 3.5 创建执行计划 3.6 部署 四、Dify-LLM应用开发平台初体验 4.1 访问Dify-LLM应用开发平台 4.2 设置管理员账户 4.3 登录Dify-LLM应用开发平台…...
NC105NC106美光固态颗粒NC108NC109
NC105NC106美光固态颗粒NC108NC109 美光固态颗粒技术矩阵深度解析:NC105/NC106/NC108/NC109的性能博弈与市场卡位 一、技术基因图谱:解密NC系列颗粒的底层架构 1. TLC与QLC的技术路线分野 美光NC系列颗粒呈现出清晰的技术分层:NC105/NC10…...
洛谷U536262 井底之“鸡” 附视频讲解
题目截图 题目背景 2024年山东财经大学新生赛的时候,xz_chicken厌倦了在鸡舍的生活,于是决定把他的主人ZQH写成QH鸡,然而除了在第一题中已经出现了ZQH所在队伍征途再起的合影,同时xz_chicken还露出其他马脚,比如说答案…...
特征筛选方法总结(面试准备15)
非模型方法 一.FILTER过滤法: 1.缺失值比例(80%以上缺失则删除)/方差 注意: 连续变量只删方差为0的,因为变量取值范围会影响方差大小。 离散类的看各类取值占比,如果是三分类变量可以视作连续变量。 函数:V…...
深入解析分布式数据库TiDB:原理、优化与架构实践
前言 在云计算与大数据时代,传统单机数据库面临三大挑战:海量数据存储、高并发访问和实时分析需求。MySQL 分库分表方案复杂、NoSQL 缺乏 ACID 支持、MPP 数仓难以处理 OLTP… 在这样的背景下,TiDB 应运而生。作为一款开源的分布式 NewSQL 数…...
YouTube视频字幕转成文章算重复内容吗?
很多创作者误以为「自己说的话不算抄袭」,却不知道YouTube自动生成的字幕早已被搜索引擎存档。 去年就有案例:某美食博主将教程视频字幕转为图文,结果原创度检测仅42%,导致页面权重暴跌。 本文揭秘5个实操技巧:从删除…...
codeup添加流水线docker自动化部署
在项目根目录下增加Dockerfile文件 # 使用基础镜像 FROM maven:3.8.4-openjdk-17-slim AS build # 设置工作目录 WORKDIR /app # 复制项目源代码 COPY . . # 构建项目 RUN mvn clean package -DskipTests # 验证JAR包是否生成 RUN ls -l target/your-project.jar # 使用合适的…...
面试点补充
目录 1. 搭建lnmp Linux 系统基础命令 nginx相关命令 MySQL 相关命令 PHP 相关命令 验证命令 下载并部署 Discuz! X3.4 论坛 到 Nginx 网站 2. 脑裂 2.1 脑裂的定义 2.2 脑裂产生的原因 1. 主备节点之间的心跳线中断 2. 优先级冲突 3. 系统或服务负载过高 2.3 如何…...
深入解析 Oracle session_cached_cursors 参数及性能对比实验
在 Oracle 数据库管理中,session_cached_cursors参数扮演着至关重要的角色,它直接影响着数据库的性能和资源利用效率。本文将深入剖析该参数的原理、作用,并通过性能对比实验,直观展示不同参数设置下数据库的性能表现。 一、sessi…...
MyBatis:动态SQL
文章目录 动态SQLif标签trim标签where标签set标签foreach标签include标签和sql标签 Mybatis动态SQL的官方文档: https://mybatis.net.cn/dynamic-sql.html 动态SQL 动态SQL是 MyBatis的强大特性之一,如果是使用JDBC根据不同条件拼接sql很麻烦,例如拼接…...
数据库性能调优:索引设计、缓存配置与查询计划优化
在高并发、大数据量场景下,数据库性能直接影响系统稳定性与用户体验。 本文将从索引设计、缓存配置、查询计划优化三大核心维度出发,结合实战案例与代码示例,系统解析数据库性能调优的关键策略,并深入讲解 EXPLAIN ANALYZE 与 索引覆盖策略 的应用技巧。 一、索引设计:从…...
安全强化的Linux
SElinux简介 SELinux是security-Enhanced Linux的缩写,意思是安全强化的linux SELinux主要由美国国家安全局(NSA)开发,当初开发的目的是为了避免资源的误用。传统的访问控制在我们开启权限后,系统进程可以直接访问 当我们对权限设置不严谨时,这种访问方式就是系统的安全漏洞 在…...
计算机网络(2)——应用层(上)
1.应用层概述 应用层(Application Layer)属于计算机网络体系结构中的最顶层,直接面向用户,提供各种网络服务和应用程序的接口 本文主要的学习内容如下: (1)网络应用进程通信方式 客户端-服务器方式点对点方式混合方式 (2)网络应用的需求与传输…...
day017-磁盘管理-实战
文章目录 1. 硬盘命名规则2. 添加硬盘2.1 查看硬盘名称 3. 硬盘分区3.1 分区命名规则:mbr分区表格式3.2 创建分区:fdisk3.2.1 fdisk -l:查看硬盘及分区信息3.2.2 fdisk /dev/sdc :为该硬盘分区3.2.3 创建扩展分区和逻辑分区3.2.4 保存设置并退…...
Win10 安装单机版ES(elasticsearch),整合IK分词器和安装Kibana
一. 先查看本机windows是否安装了ES(elasticsearch),检查方法如下: 检查进程 按 Ctrl Shift Esc 组合键打开 “任务管理器”。在 “进程” 选项卡中,查看是否有 elasticsearch 相关进程。如果有,说明系统安装了 ES。 检查端口…...
STM32 控制 OLED 全攻略(二):实现字符和汉字的显示
目录 一 前言 二 OLED介绍 (一)SSD1306 (二)OLED屏幕 三 显示原理结合代码解释 1 指令---0x00 2 数据---0x40 3 初始化oled函数 4 codetab.h 四 显示字符串的原理 🧾 ASCII 编码范围: ✅ OLED_S…...
c#将json字符串转换为对象数组
在C#中,将JSON字符串转换为对象数组是一个常见的需求,特别是在处理来自Web API的响应或需要反序列化本地文件内容时。这可以通过使用Newtonsoft.Json(也称为Json.NET)库或.NET Core内置的System.Text.Json来完成。以下是如何使用这…...
Cryosparc里头restack的妙用
在Cryosparc里头经常需要迁移job或者将particle打包成relion可以识别的模式,总是会遇到一个问题,我们需要的颗粒明明很少,但总是保存出一大堆东西来。原因就是,他会把最开初的particle都给你算进来,而不是某个作业对应…...
.bat文档如何运行Python程序
.bat文档如何运行Python程序 在Windows操作系统中,你可以通过几种方式来运行Python程序,即使是通过.bat批处理文件。.bat文件是一种批处理脚本,它允许你执行一系列命令。以下是一些步骤和示例,说明如何从.bat文件运行Python程序。…...
力扣HOT100之二叉树:230. 二叉搜索树中第 K 小的元素
这道题直接用最笨的办法来做的,用递归来做,我们定义一个全局变量vector<int> element,然后使用中序遍历,每当碰到一个非空节点就将其加入到向量中,这样依赖当向量中的元素小于k时,就返回0,…...
【Nextcloud】使用 LNMP 架构搭建私有云存储:Nextcloud 实战指南
目录 一、环境准备与基础配置 1. 系统环境要求 2. 初始化系统配置 二、搭建 LNMP 基础架构 1. 一键安装 LNMP 组件 2. 启动数据库服务 三、部署 Nextcloud 存储服务 1. 上传并解压安装包 2. 设置目录权限(测试环境配置) 3. 配置 MariaDB 数据库…...
已知6、7、8月月平均气温和标准差,求夏季季平均温度与标准差
由下面定理,得出平方和的公式:(即每天的温度平方和) 这样就可以推出季平均的算法: 举例:在Excel用公式算,不要手算: 因此季平均:(B2*C2B3*C3B4*C4)/SUM(B2:B4) 季标准差…...
【cursor指南】cursor免费续杯pro会员试用
背景 心血来潮(其实是被逼的),开始需要cursor里面的agent对话。cursor用着用着就会出现点数耗尽、试用到期等问题,于是自行开始找免费的cursor会员续用方法。 Part01:参考链接鸣谢 1. Cursor 全攻略:注册、使用到无限续杯&…...
Visual Studio解决方案构建三剑客:生成/重新生成/清理完全指南(实战经验总结)
文章目录 当你在VS里右键解决方案时...一、先看实战场景(老板发飙警告)二、三大命令解剖课(重点标记版)2.1 生成解决方案(F7)2.2 重新生成解决方案(CtrlAltF7)2.3 清理解决方案&…...
《JVM如何判断一个对象可以被回收?图文详解GC Root算法》
大家好呀!我是你们的老朋友Java技术博主👋 今天咱们来聊聊Java虚拟机(JVM)中一个超级重要的话题——垃圾回收机制(Garbage Collection)和GC Root可达性分析!这可是Java程序员必须掌握的核心知识点哦!😎 🌟…...
常用算法/机理模型演示平台搭建(一)
算法/机理模型演示平台搭建 一、算法列表(app/algorithms)二、行业机理模型 (app/models)三、如何使用本项目旨在为初学者提供 35种 常用算法和 9种 行业机理模型的简单Python实现或概念说明。每个算法都有其独特的应用场景,从数据预测、质量检测、过程控制到结构分析和优化问…...
一文详解红黑树
一文详解红黑树 前言一、基本概念与特性1.1 红黑树的定义1.2 红黑树的特性 二、红黑树的节点结构与表示三、红黑树的基本操作3.1 插入操作3.2 删除操作 四、红黑树的应用场景4.1 编程语言的集合类4.2 数据库索引4.3 Linux 内核进程调度 总结 前言 在数据结构的领域中ÿ…...
Windows 安装显卡驱动
1.第一步:打开Nvidia 官网驱动下载页面 2.第二步:选择相关信息, 玩游戏选择,GeForce Game Ready ,创意设计、摄影直播 选择 NVIDIA Studio 驱动程序 (NVIDIA Studio Driver - WHQL.) 2.第三步࿱…...
【C语言】易错题 经典题型
出错原因:之前运行起来的可执行程序没有关闭 关闭即可 平均数(average) 输入3个整数,输出它们的平均值,保留3位小数。 #include <stdio.h> int main() {int a, b, c;scanf("%d %d %d", &a, &…...
C++类与对象--5 运算符重载
对已有的运算符进行重新定义,赋予不同的功能,以适应不同的数据类型 5.1 加号运算符 实现两个自定义数据类型的加运算 (1)通过成员函数实现“”重载 class Number { public:Number(int a, int b):m_A(a),m_B(b){}Number(){}Number operator(Number &a…...
接口排查不能靠猜:实战中如何用抓包工具精准定位问题(含 Charles 使用示例)
几乎每个写代码的开发者都经历过这样的时刻:接口突然返回空、请求超时、前端数据没更新……你试过重启服务、翻查日志、改代码打印,最后还是无解。 我想说,其实很多问题的答案都藏在“网络请求”里,只是你没有去看。 这篇文章&a…...
【占融数科-注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
4.7 时间模块
时间模块: * 1. time:操作时间本身 2.datetime:主要用于设置某一时间 3.calendar:主要用于时间份量计算 import time # 1. actimr:把一个表示时间的元组转换为字符串。要是不给出参数则返回当前本地时间。 print(time.asctime())…...
SHIMADZU岛津 R300RC300 Operation Manual
SHIMADZU岛津 R300RC300 Operation Manual...
(C语言篇)处理字符串的四个基础函数
strlen、strcpy、strcat、strcmp使用以及注意事项 在C语言中,strlen、strcpy、strcat、strcmp是处理字符串的四个基础函数,都在<string.h>头文件中声明。下面为你详细介绍它们的功能、用法和注意事项。 1. strlen - 计算字符串长度 函数原型&am…...
mysql的安装方式
1.yum/apt安装 yum安装: 先搭建yum仓库,可以在清华源内找:mysql | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror vim /etc/yum.repos.d/mysql.repo[mysql-connectors-community] nameMySQL Connectors Communit…...
嵌入式(C语言篇)Day11
嵌入式Day11 一、动态内存分配核心函数 (一)函数列表 函数名功能头文件返回值malloc分配连续的size字节堆内存stdlib.h成功返回首地址(void*),失败返回NULLcalloc分配num个元素size字节/元素的堆内存,自…...
Java集合框架解析:从基础到底层源码
Java集合框架解析:从基础到底层源码 一、集合体系 1.1 两大核心接口深度解析 Collection 单列集合 List 系列 ArrayList:动态数组实现,初始容量10,扩容策略为 原容量的1.5倍// JDK17 扩容源码片段 int newCapacity oldCapacity…...
C语言实现android/linux按键模拟
C语言实现 input事件模拟 #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <linux/input.h>int main() {int fd open("/dev/input/event0", O_RDWR);if (fd < 0) {perror("Failed to open device");ret…...
VisionPro:轴承错位标识
找出轴承缺陷并标记:效果 1.打开导入图片 2.添加CogToolblock:方便后续写代码 3.对零件进行模板匹配 4.对图片进行预处理(重点) 5.添加找圆工具和展开工具 根据下图将线链接 6.添加模板匹配工具并运行 7.训练模板 好的全找出来 8.代码编写 红色框为添加的代码(下面有完整代码) …...
专题五:floodfill算法(扫雷游戏精讲)
以leetcode529题 题目解析: M表示:未挖出的地雷 E表示:未挖出的空白方块 什么叫未挖出,就是你没玩的时候,棋盘是什么样的,就是你站在上帝视角看待棋盘 B:表示挖出来是空白的,如…...
MySQL企业版免费开启,强先体验
近期Oracle突然宣布,MySQL企业版面向开发者免费开放下载,这一消息瞬间引爆DBA圈。作为数据库领域的“顶配车型”,企业版长期因高昂授权费让中小团队望而却步,如今免费开放无异于“劳斯莱斯开进菜市场”。 本文将深度拆解企业版的…...
React Contxt详解
React Contxt详解 React 的 Context API 是用于跨组件层级传递数据的解决方案,尤其适合解决「prop drilling」(多层组件手动传递 props)的问题。以下是关于 Context 的详细解析: 文章目录 React Contxt详解一、Context 核心概念二…...
前端工程的相关管理 git、branch、build
环境配置 标准环境打包 测试版:npm run build-test 预生产:npm run build-preview 正式版:npm run build 建议本地建里一个 .env.development.local 方便和后端联调时修改配置相关信息。 和 src 同级有一下区分环境的文件: .env.d…...
鸿蒙 Location Kit(位置服务)
移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。 Location Kit 使用多种定位技术提供服务,可以准确地确定设备在室外/室…...