有关资源泄漏的一些知识

​​​​​​内存泄漏

1.具体解释

1.1定义 :动态分配的内存(如通过 new、malloc)未被正确释放,导致程序运行期间内存占用持续增长,最终可能耗尽系统资源。

1.2常见场景

1.2.1异常抛出导致 delete 未执行:

cpp 复制代码
void foo() {
    int* p = new int(42);
    throw std::runtime_error("Error"); // 异常抛出,p 未释放
    delete p; // 不会执行
}

1.2.2循环中分配内存但未释放:

cpp 复制代码
while (true) {
    int* p = new int[1000]; // 每次循环分配,但未释放
}

1.2.3对象析构时未释放成员指针:

cpp 复制代码
class BadExample {
    int* data;
public:
    BadExample() : data(new int[100]) {}
    ~BadExample() { /* 忘记 delete[] data; */ } // 泄漏
};

1.2影响:程序性能下降、崩溃(OOM),长期运行的服务可能因内存耗尽被系统终止

1.3防范

1.3.1使用智能指针(std::unique_ptr、std::shared_ptr)自动管理内存

1.3.2遵循RAII(资源获取即初始化) 原则,将资源绑定到对象生命周期

文件描述符泄漏

1.具体解释

2.1定义:打开的文件或套接字未被关闭,导致系统文件描述符耗尽(Linux 默认限制通常为 1024~65536)

2.2常见场景

2.2.1未调用 close() 或 fclose():

cpp 复制代码
void readFile() {
    FILE* f = fopen("data.txt", "r");
    if (f) {
        // 处理文件...
        // 忘记 fclose(f); // 泄漏
    }
}

2.2.2异常路径未关闭文件:

cpp 复制代码
void processFile() {
    int fd = open("data.txt", O_RDONLY);
    if (fd == -1) return;
    // 处理文件...
    if (error_occurred) throw std::runtime_error("Error"); // fd 未关闭
    close(fd); // 可能跳过
}

2.影响:无法打开新文件或网络连接,系统功能受限。

3.防范

2.3.1使用 RAII 封装文件操作(如 std::ifstream、std::ofstream)

2.3.2自定义文件句柄管理类,析构时自动关闭:

cpp 复制代码
class FileHandle {
    int fd;
public:
    FileHandle(const char* path) : fd(open(path, O_RDONLY)) {}
    ~FileHandle() { if (fd != -1) close(fd); }
};

锁泄漏

1.具体解释

3.1定义:获取的锁(如互斥量 std::mutex)未被释放,导致其他线程永久阻塞。

3.2常见场景

3.2.1未调用 unlock():

cpp 复制代码
std::mutex mtx;
void criticalSection() {
    mtx.lock();
    // 处理共享数据...
    // 忘记 mtx.unlock(); // 泄漏
}

3.2.2异常抛出导致锁未释放:

cpp 复制代码
void riskyOperation() {
    std::lock_guard<std::mutex> lock(mtx); // 正确:RAII 自动释放
    // 若使用手动锁:
    mtx.lock();
    throw std::runtime_error("Error"); // 锁未释放
    mtx.unlock();
}

2.影响:线程死锁,系统响应变慢或崩溃

3.防范

3.3.1优先使用 std::lock_guard 或 std::unique_lock 自动管理锁生命周期

3.3.2避免在持有锁时调用可能抛异常的函数。

网络资源泄漏

1.具体解释

4.1定义:未正确关闭网络连接(如套接字、数据库连接),导致资源耗尽或连接池枯竭。

4.2常见场景

4.2.1未调用 close() 或 disconnect()

4.2.2数据库连接未归还

2.影响:网络服务不可用,数据库连接数超限。

3.防范

4.3.1使用 RAII 封装网络资源(如 std::unique_ptr 自定义删除器)。

4.3.2连接池实现自动回收机制。

循环引用导致的内存泄漏

1.具体解释

5.1定义:在引用计数智能指针(如 std::shared_ptr)中,两个对象相互引用,导致引用计数永远无法归零

5.2常见场景

cpp 复制代码
struct Node {
    std::shared_ptr<Node> next;
    std::shared_ptr<Node> prev; // 双向循环引用
};
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b;
b->prev = a; // 引用计数均为 2,离开作用域后不会释放

2.影响:内存无法回收,即使对象不再使用。

3.防范:使用 std::weak_ptr 打破循环

相关推荐
小大宇1 小时前
Vue知识点6-computed计算属性
前端·javascript·vue.js
程序员海军1 小时前
尤雨溪 : Vue 4 已经在规划中了!
前端·javascript·vue.js
2601_949970692 小时前
HumanizeDuration 跨端三方库仓颉适配全流程
前端·javascript·flutter
风骏时光牛马3 小时前
后端服务接口开发与性能优化
前端
kyriewen4 小时前
我让 4 个 AI 互相 review 代码,最温柔的那个下手最狠
前端·程序员·ai编程
计算机魔术师4 小时前
493家公司白砸AI钱?Apollo这组数据戳破了幻觉
前端
IT_陈寒4 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
柳杉4 小时前
用 Codex 完成智慧高速 3D 可视化大屏,从 18 张行业设计稿到可交互的运行监测中心
前端·ai编程·数据可视化
review445435 小时前
拿到 codex 第一步
前端·agent·vibecoding
鶴哥只手遮天5 小时前
jQuery 4.0 源码架构与工程实践-第 01 章 · 全景与工程结构:一个 20 岁库的自省
前端·javascript·jquery