当前位置:首页>Linux>Linux系统内存优化+性能优化应该如何做?

Linux系统内存优化+性能优化应该如何做?

  • 2026-10-11 08:27:18
Linux系统内存优化+性能优化应该如何做?
一、内存优化
1、内存泄漏排查与治理
  • 使用 valgrind --leak-check=full 定位内存泄漏点。
  • 结合 addr2line 定位到具体代码行。
  • 对长期运行的服务,做内存增长趋势监控,发现异常增长及时修复。
  • 规范编码:成对 malloc/free、new/delete,智能指针替代裸指针。
2、内存碎片优化
  • 对频繁申请释放的小对象,实现内存池 / 对象池,减少系统调用和碎片。
  • 避免频繁申请小块内存,改用大块预分配、复用。
  • 对长期运行服务,避免运行中大量动态扩容,减少碎片累积。
3、栈溢出与栈使用优化
  • 避免在栈上定义大数组、大结构体。
  • 调整线程栈大小,避免不必要的大栈空间浪费。
4、共享内存与匿名内存优化
  • 多进程间使用共享内存减少拷贝,降低整体内存占用。
  • 对大缓存使用 mmap 减少内存拷贝,提升效率。
5、OOM内存定位
  • 通过 /proc/pid/smaps、dmesg 分析 OOM 触发原因。
  • 优化内存高峰,避免瞬时内存暴涨。
二、性能优化
1、CPU性能优化
  • 使用 top、perf top 定位 CPU 高占用函数。
  • 减少死循环、空转、无效计算。
  • 优化热点函数,减少递归、冗余计算、重复逻辑。
  • 对计算密集型模块做算法优化,降低时间复杂度。
2、锁与并发优化
  • 使用 pstack、gdb 排查死锁、锁竞争。
  • 减少锁粒度:用细粒度锁、自旋锁、无锁设计。
  • 降低锁冲突:分段锁、局部变量替代共享变量。
  • 避免长时间持有锁,减少阻塞。
3、IO与系统调用优化
  • 使用 strace 发现大量重复系统调用(频繁 read/write/open)。
  • 合并 IO、批量读写,减少用户态与内核态切换。
  • 使用缓冲区减少磁盘 / 网络 IO 次数。
4、网络性能优化
  • 减少不必要的网络请求,合并包,降低延迟。
  • 设置合理的 socket 缓冲区,优化 TCP 参数。
  • 避免频繁 connect/close,使用长连接、连接池。
5、多线程/进程调度优化
  • 避免线程过多导致频繁切换(pidstat -t 观察)。
  • 绑定 CPU 核心(taskset)降低上下文切换。
  • 区分 IO 密集型与 CPU 密集型线程,分开调度。
三、总结
内存方面:
  • 使用 valgrind、smaps 定位内存泄漏,规范智能指针与内存管理。
  • 对高频小对象实现内存池,减少内存碎片和 malloc 开销。
  • 避免栈溢出,优化大内存结构,控制内存增长趋势。
  • 定位并解决线上 OOM 问题。
性能方面:
  • 使用 perf、strace 定位 CPU 热点与系统调用瓶颈,优化热点路径。
  • 排查并解决多线程死锁、锁竞争问题,优化锁粒度。
  • 减少 IO 与系统调用次数,合并读写,使用缓冲区提升效率。
  • 优化线程模型,减少上下文切换,对关键线程做 CPU 亲和性绑定。
  • 对网络模块做长连接、连接池优化,降低延迟。
四:追问
1、怎么定位死锁?
  • 先用 top 找到进程 PID,看 CPU 使用率很低但业务卡住。
  • 使用 gdb -p PID 附加进程。
  • info threads
     查看所有线程状态。
  • thread apply all bt
     打印所有线程栈。
  • 观察是否有线程都阻塞在 pthread_mutex_lock、futex 等函数,并且形成循环等待。
  • 也可以用 pstack PID 快速看调用栈,判断是否互相等待锁。
2、怎样判断是锁竞争还是死锁?
  • 死锁
    线程都阻塞不动,CPU 很低,栈显示互相等锁,业务完全卡死。
  • 锁竞争
    CPU 很高,线程频繁切换,大量系统调用(futex),业务跑不动但线程一直在活动。
简单记:
死锁 = 卡住不动,CPU 低
锁竞争 = 跑不起来,CPU 高
3、内存池怎么实现?为什么要使用内存池?
  • 频繁 malloc/free 会产生内存碎片,且有系统调用开销。
  • 内存池预先向系统申请一大块内存,内部自己管理小块分配。
  • 结构一般是:
    • 固定大小块(如 32B、64B、128B)
    • 空闲链表管理空闲块
    • 分配时直接从链表取,释放归还链表
  • 好处:减少系统调用、降低碎片、提升分配速度。
4、如何用strace排查性能问题?
  • strace -p PID附加进程,看系统调用。
  • 观察是否大量重复调用:open/read/write/futex 等。
  • 大量 futex 说明锁竞争激烈。
  • 大量 read/write 说明 IO 过于频繁,需要合并、加缓存。
  • 用 -c 统计耗时,看哪个系统调用占比最高。
  • 用 -o 保存日志,分析阻塞点。
5、如何用perf找CPU热点?
  • perf top -p PID
     实时看 CPU 占用最高的函数。
  • perf record -g -p PID
     采样记录。
  • perf report
     查看调用链,定位热点函数。
  • 看是业务函数耗 CPU,还是库函数、内核函数耗 CPU。
  • 热点如果是无效循环、冗余计算,就做算法优化;如果是锁竞争,就优化并发。
6、遇到CPU占用高达100%如何排查?
  • top
     看哪个进程 CPU 100%。
  • top -H -p PID
     看是哪个线程占满。
  • printf "%x\n" 线程TID
     转十六进制。
  • gdb -p PID
     或 pstack 看该线程栈。常见原因:
  1. 死循环
  2. 锁竞争激烈
  3. 大量正则 / 字符串处理
  4. 频繁 GC(如果是带 GC 语言)
  5. 大量系统调用
7、遇到内存泄漏怎么排查?
  • 观察 topfree 内存持续上涨。
  • valgrind --leak-check=full ./程序
     直接跑,定位泄漏位置。
  • 线上用 pmap -x PID 看内存分布。
  • /proc/[PID]/smaps
     看虚拟内存、匿名页大小。
  • 结合 addr2line 把地址转成代码行。
  • 修复:成对释放、智能指针、对象池复用。
8、怎么排查进程卡住(假死)?
  • strace -p PID
     看最后停在哪个系统调用。
    • 停在 futex:锁等待 / 死锁
    • 停在 read/recv/connect:网络阻塞
    • 停在 wait:等子进程
  • gdb
     看线程栈,确认阻塞原因。
  • 看日志、网络状态、文件句柄是否异常。

最新文章

随机文章