碎片学习
📚

碎片学习

Tags
杂项
Published
March 28, 2021
Author
👏 记录一些碎片化的技术知识点。可能是看到的技术点、面试题目、工作遇到的问题等等。我会将问题和个人思考及答案作为记录整理。方便日后查询。
😌 随时更新 ......
 
 
Golang内存分配逃逸分析
注意我们此处谈到的堆和栈是对操作系统中的,这个和数据结构中的堆和栈还是又一定区别的。 栈 可以简单得理解成一次函数调用内部申请到的内存,它们会随着函数的返回把内存还给系统。 类似于上面代码里面的temp变量,只是内函数内部申请的临时变量,并不会作为返回值返回,它就是被编译器申请到栈里面。 再来看看堆得情况之一如下代码: 而上面这段代码,申请的代码一模一样,但是申请后作为返回值返回了,编译器会认为变量之后还会被使用,当函数返回之后并不会将其内存归还,那么它就会被申请到 堆 上面了。 我们再看看如下几个例子: 所谓逃逸分析(Escape analysis)是指由编译器决定内存分配的位置,不需要程序员指定。 在函数中申请一个新的对象: 注意,对于函数外部没有引用的对象,也有可能放到堆中,比如内存过大超过栈的存储能力。 Go可以返回局部变量指针,这其实是一个典型的变量逃逸案例,示例代码如下: 虽然 在函数 StudentRegister() 内部 s 为局部变量,其值通过函数返回值返回,s 本身为一指针,其指向的内存地址不会是栈而是堆,这就是典型的逃逸案例。 终端运行命令查看逃逸分析日志: 可见在StudentRegister()函数中,也即代码第9行显示"escapes to heap",代表该行内存分配发生了逃逸现象。 上面代码Slice()函数中分配了一个1000个长度的切片,是否逃逸取决于栈空间是否足够大。 直接查看编译提示,如下: 所以只是1000的长度还不足以发生逃逸现象。然后就x10倍吧 分析如下: 当切片长度扩大到10000时就会逃逸。 实际上当栈空间不足以存放当前对象时或无法判断当前切片长度时会将对象分配到堆中。 很多函数参数为interface类型,比如fmt.Println(a ...interface{}),编译期间很难确定其参数的具体类型,也能产生逃逸。 如下代码所示: 逃逸分下如下: D:\SourceCode\GoExpert\src>go build -gcflags=-m # _/D_/SourceCode/GoExpert/src .\main.go:7: s escapes to heap .\main.go:7: main ...
Golang内存分配逃逸分析
 
 
 
 
 
cron 僵尸进程问题分析
前段时间遇到一个比较诡异的问题, 一台服务器上突然出现了许多僵尸进程。 多数时候,这些僵尸进程出现在早上,大概到了下午又自动消失。 第二天又重复这样的情况。 查了下,这些僵尸进程的父进程都是一些挂在 cron 下的 bash 进程。 猜测是 cron 每天早上定时执行了某些任务留下了这些僵尸进程. 为什么会出现僵尸进程,以及,为什么这些僵尸进程到了下午又自己消失了? 一开始希望直接从 cron 配置定位产生僵尸进程的任务, 检查发现这台机器上配置了相当数量的 cron 任务,逐一排查过去不现实,只能寻找其他思路. 僵尸进程意味着该进程已经执行结束, 但是父进程还没有调用 wait() 获取它的返回值, 从而导致已结束的进程进程处于僵尸(zombie)进程状态。 正常而言,一个进程结束后通常会在短暂的时间内处于僵尸进程状态. 长时间处于僵尸进程状态, 意味着父进程一直都没有调用 wait() , 所以我们首先检查下这些僵尸进程的父进程也就是 cron 进程在干什么。 可以看到 2584 这个僵尸进程的父进程 2582 处于睡眠状态。 strace 显示 2582 进程在等待在 read() 系统调用。 read()系统调用读取的文件描述符是 6, 利用 lsof 指令来查看这个文件描述符的详细信息。 可以看到这是个管道文件, 对应 inode 是 13865。 进程 2582 处于管道读的一端, 根据这个 inode 信息, 我们可以利用 lsof 进一步找出管道写的一端关联的进程。 根据 lsof 的输出,大致可以断定 2586 和 18826 这两个进程把标准输出和错误输入都重定向到管道 6 写的一端了。 经过检查发现 2586 进程执行的 sleep.sh 脚本就是 cron 下的定时任务之一。 但是 ps 指令却显示,2586 任务进程的父进程是 init 进程。 根据目前的分析,大概可以猜测会出现 bash 僵尸进程的直接原因--父进程卡在管道读的一端上而没法继续调用 [wait()函数]. 但是我们还需要搞清楚: bash 僵尸进程的父进程为什么会卡在管道读的一端上.
cron 僵尸进程问题分析