有关资源泄漏的一些知识

​​​​​​内存泄漏

1.具体解释

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

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_ptrstd::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::ifstreamstd::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_guardstd::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 打破循环

相关推荐
随风一样自由7 小时前
【前端独角兽】刚进入前端领域的前端开发用jQuery还是Vue3?
前端·javascript·vue3·jquery
IMPYLH7 小时前
HTML 的 <data> 元素
前端·html
YHHLAI8 小时前
[特殊字符] 面试中的 Promise —— 从入门到精通
前端·javascript·面试
kyriewen10 小时前
我扒了 GPT-5.6 的全部编程跑分——有一项 OpenAI 没敢放出来
前端·gpt·ai编程
前端H10 小时前
微前端 v3 架构升级:从加载隔离到状态协同
前端·架构·状态模式
陆枫Larry11 小时前
小程序包体积优化:用 SVG 图片替换 iconfont,并保留 CSS 控色能力
前端
环境栈笔记12 小时前
多账号浏览器选型检查清单:Profile、权限、Session 和任务日志怎么评估
前端·人工智能·后端·自动化
前端炒粉13 小时前
手写promise
java·前端·javascript
LaughingZhu13 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
jsonbro13 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式