内存泄漏示例:为什么不释放会出问题

副标题 / 摘要 内存泄漏会让程序“越跑越慢”。本文用 C 示例展示泄漏原因,并给出基本规避方法。 目标读者 写过 C/C++ 的开发者 关注资源管理与稳定性的工程师 学习系统编程的读者 背景 / 动机 在手动内存管理语言中,忘记释放会导致内存逐渐耗尽。 长期运行服务最容易遭遇此类问题。 核心概念 内存分配:malloc/new 释放:free/delete 泄漏:分配后没有释放且失去引用 实践指南 / 步骤 所有分配都必须有对应释放 明确资源的所有权 使用工具检测泄漏(valgrind) 用 RAII 或智能指针减少风险 可运行示例 #include <stdlib.h> #include <stdio.h> int main() { for (int i = 0; i < 100000; i++) { char *p = (char *)malloc(1024); if (p == NULL) return 1; // 忘记 free(p); -> 内存泄漏 } printf("done\n"); return 0; } 解释与原理 每次 malloc 都会向堆申请内存,如果不释放,内存不会回收。 循环中持续泄漏最终会导致内存耗尽。 常见问题与注意事项 垃圾回收语言就不会泄漏吗? 也可能“逻辑泄漏”,比如全局容器无限增长。 为什么泄漏很难发现? 因为短期运行可能看不出问题。 工具有用吗? 非常有用,建议上线前检查。 最佳实践与建议 用智能指针或 RAII 自动释放 对长期运行服务做内存监控 建立内存泄漏回归测试 小结 / 结论 内存泄漏是资源管理失控的典型问题。 通过明确所有权与工具检测,可以显著降低风险。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]

手写一个最小的垃圾回收器:标记-清除模型

副标题 / 摘要 标记-清除是最基础的垃圾回收模型。本文用简化示例解释“可达性”与回收过程。 目标读者 想理解 GC 原理的开发者 系统编程与语言设计学习者 关注内存管理的工程师 背景 / 动机 手动内存管理容易出错,而 GC 通过“可达性”自动回收对象。 理解基础模型有助于调试内存问题。 核心概念 根集合(Roots):直接可达的对象 可达性:从根出发可访问到的对象 标记-清除:标记存活对象,清除不可达对象 实践指南 / 步骤 构建对象图与引用关系 从根集合进行标记遍历 清除未被标记的对象 输出回收结果 可运行示例 class Obj: def __init__(self, name): self.name = name self.refs = [] self.marked = False def mark(obj): if obj.marked: return obj.marked = True for r in obj.refs: mark(r) def sweep(heap): return [o for o in heap if o.marked] if __name__ == "__main__": a = Obj("a") b = Obj("b") c = Obj("c") a.refs.append(b) heap = [a, b, c] roots = [a] for r in roots: mark(r) heap = sweep(heap) print([o.name for o in heap]) # c 被回收 解释与原理 GC 的核心是假设“不可达对象可以回收”。 标记阶段找到存活对象,清除阶段释放其他对象。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]

什么是栈与堆:内存模型的关键区别

副标题 / 摘要 栈与堆是两种常见的内存分配模型。本文解释它们在生命周期、分配成本与适用场景上的差异。 目标读者 想理解内存模型的开发者 需要优化性能与内存的工程师 学习语言底层机制的同学 背景 / 动机 很多性能问题来自对内存模型的误解。 理解栈与堆能帮助你写出更稳定、更高效的代码。 核心概念 栈(Stack):函数调用时自动分配,LIFO 堆(Heap):运行期动态分配,需要显式释放或 GC 生命周期:栈随作用域结束自动释放 实践指南 / 步骤 局部临时数据优先放栈 需要跨作用域共享的对象放堆 避免频繁堆分配 关注 GC 或释放成本 在性能关键路径上减少堆对象 可运行示例 #include <stdio.h> #include <stdlib.h> int main(void) { int a = 10; // 栈上 int *p = malloc(sizeof(int)); // 堆上 *p = 20; printf("%d %d\n", a, *p); free(p); return 0; } 解释与原理 栈分配快、释放自动,但生命周期短。 堆分配更灵活,但成本高且需要额外管理(GC 或 free)。 常见问题与注意事项 栈一定更快吗? 一般更快,但栈空间有限。 堆对象一定要手动释放吗? 取决于语言,有 GC 的语言会自动回收。 栈溢出是什么? 递归过深或局部变量过大导致栈空间耗尽。 最佳实践与建议 频繁创建对象时考虑对象池 对大对象避免放在栈上 监控 GC 压力与分配热点 小结 / 结论 栈与堆的差异决定了性能与内存管理策略。 理解内存模型是写出稳定系统的基础。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]