为什么CPU的字节序至今无法统一:从鸡蛋争议到网络标准
1980年,互联网工程备忘录IEN 137发表了一篇题为《On Holy Wars and a Plea for Peace》的论文。作者Danny Cohen用《格列佛游记》中的鸡蛋争议,比喻计算机界关于字节序的争论。四十多年过去了,这场"圣战"不仅没有结束,反而因为新硬件、新协议的出现变得更加复杂。 ...
1980年,互联网工程备忘录IEN 137发表了一篇题为《On Holy Wars and a Plea for Peace》的论文。作者Danny Cohen用《格列佛游记》中的鸡蛋争议,比喻计算机界关于字节序的争论。四十多年过去了,这场"圣战"不仅没有结束,反而因为新硬件、新协议的出现变得更加复杂。 ...
每一个 C 程序员都遇到过这样的错误:undefined reference to 'foo' 或 multiple definition of 'bar'。编译通过了,但链接器拒绝了你的代码。那一刻,你可能只会机械地检查头文件、库路径或声明顺序,然后继续工作。但你是否想过,链接器究竟在做什么?为什么它能容忍某些重复定义,却对另一些报错?为什么同一个程序在静态链接和动态链接下行为不同? ...
一个全局变量的"分身术" 1979年,Unix V7引入了一个特殊的全局变量——errno。当系统调用失败时,它会将错误码写入这个变量,供后续代码检查。这在单线程时代完美运作。但到了1990年代,多线程编程成为主流,问题出现了:如果两个线程同时执行系统调用,它们会覆盖彼此的errno值。 ...
当你按下Ctrl+C时,终端里的程序就停止了。这个每天都在发生的操作背后,是Unix操作系统最古老也最精妙的进程间通信机制——信号(Signal)。 ...
1982年3月,Bill Joy在BSD开发过程中添加了chroot系统调用,约一年半后随4.2BSD正式发布。这个简单的功能让进程看到一个被重新定义的根文件系统,被认为是现代容器技术的起点。但chroot只是文件系统的隔离,进程仍然共享同一个内核视图,看到相同的进程列表、网络配置和主机名。 ...
当你在C代码中写下一行简单的函数调用result = add(a, b, c),编译器需要回答一系列问题:参数a、b、c应该放在哪里?是寄存器还是栈?如果是寄存器,用哪些?返回值result又该如何传递?调用前后谁负责保存寄存器?栈指针需要调整多少? ...
title: “内存分配器为何成为高并发服务器的隐形瓶颈:从ptmalloc到mimalloc的四十年技术博弈” date: “2026-03-07T07:47:31+08:00” description: “深入解析内存分配器的演进历程,从dlmalloc的设计原理到ptmalloc的多线程扩展,从jemalloc的arena架构到tcmalloc的per-CPU缓存,再到mimalloc的free list sharding创新。揭示高并发环境下内存分配的性能瓶颈、内存碎片的本质原因,以及如何根据工作负载选择合适的内存分配器。” draft: false categories: [“系统编程”, “性能优化”] tags: [“内存分配器”, “jemalloc”, “tcmalloc”, “mimalloc”, “ptmalloc”, “内存碎片”, “多线程性能”, “系统调优”] 2017年,某支付平台的技术团队发现一个诡异现象:服务器运行一段时间后,RSS(Resident Set Size)持续增长,最终达到堆内存的三倍以上。排查后发现,问题出在glibc的默认内存分配器——即使应用层正确释放了内存,分配器却未能将物理内存归还给操作系统。 ...