🌱 Memory Leak trong Lập Trình Nhúng: Nguyên Nhân và Ví Dụ

🌱 Memory Leak trong Lập Trình Nhúng: Nguyên Nhân và Ví Dụ

Khi phát triển phần mềm nhúng, lập trình viên thường gặp nhiều khó khăn, đặc biệt là những "bug kỳ lạ" - kỳ lạ một phần do chẳng biết nó đến từ đâu cả 😅 Đặc biệt với anh em làm phần mềm nhúng, thì mất cái kỳ lạ này còn thường xuyên xảy ra hơn:

  • Code vừa chạy ngon xong nhưng mà chạy lại thì báo lỗi.
  • Run thì báo lỗi tùm lum nhưng debug từng bước thì lại đúng.
  • Treo mạch 😑

👉 Các vấn đề thường gặp khi thiết kế phần mềm nhúng

Có rất nhiều vấn đề xung quanh các lỗi này, vì vậy, mình chỉ nêu ra một số vấn đề tiêu biểu để anh em cùng bàn luận:
  • Vấn đề về quản lý tài nguyên (chân cẳng, bộ nhớ)
  • Vấn đề quản lý các ngắt - thiết kế luồng quản lý chương trình hợp lý
  • Vấn đề lập lịch - quản lý task trong hệ điều hành
  • Vấn đề thiết kế chương trình
Bài viết này mình sẽ nói về một vấn đề trong quản lý tài nguyên, mà cụ thể là bộ nhớ, đó là Memory Leak.
Có thể nói đây là một vấn đề rất đặc trưng của Embedded Software so với những anh em Software khác, vì lúc họ nói về RAM 8G, bộ nhớ trong 512GB thì chúng ta lại lủi thủi với những bo mạch 4GB bộ nhớ (là loại siêu nhiều 😆). Chính vì vậy, việc thường xuyên phải đối mặt với những vấn đề về bộ nhớ, việc chuẩn bị những cách xử lý trước khi nó xảy là điều mà anh em Embedded Software Developer cần phải chuẩn bị trước.

👉 Memory Leak là gì?

Trong khoa học máy tính, Memory Leak - Rò rỉ bộ nhớ là một dạng rò rỉ tài nguyên xảy ra khi chương trình máy tính quản lý không chính xác việc cấp phát bộ nhớ theo cách bộ nhớ không cần dùng nữa, mà lại không được giải phóng.

Anh em lập trình C nghe có thể nghĩ ngay đến trường hợp dùng malloc() nhưng không free() đúng không? Trên thực tế thì có rất nhiều trường hợp có thể gây ra Memory Leak:

  • Thiếu bộ nhớ RAM (Stack Overflow, Heap Overflow, ...)
  • Đọc/Ghi tràn mảng, khi đọc ghi quá số phần tử max của mảng cũng có thể gây ra các vấn đề về bộ nhớ. Tuy nhiên, một số Compiler đã hỗ trợ báo build fail để cảnh báo cho người lập trình.
  • Tràn biến, chia cho 0, ...
  • Và cái lỗi thường gặp, malloc() nhưng quên free(). Một khi đã malloc() thì anh em thường rất "tham lam" dùng toàn mảng với struct (Đối với bộ nhớ nhỏ của Vi điều khiển thì chỗ này chiếm khá nhiều). Mà một khi dùng xong quên free thì không khác gì đặt thêm mấy cái quả tạ trăm cân ở giữa nhà bếp !!!

👉 Một số ví dụ về Memory Leak trong lập trình nhúng

💬 Ví dụ 1: Cấp phát bộ nhớ trong vòng lặp

#include <stdlib.h>
#include <stdio.h>

#define LOOPS    10
#define MAXSIZE  256

int main(int argc, char **argv)
{
    int count = 0;
    char *pointer = NULL;
    for(count=0; count<LOOPS; count++) 
    {
        pointer = (char *)malloc(sizeof(char) * MAXSIZE);
    }
    free(pointer);
    return count;
}

Trong ví dụ này, chúng ta được cấp phát 10 block ô nhớ với kích thước là MAXSIZE = 256 để có thể làm những công việc khác nhau. Với một vòng for như trên thì pointer sẽ chỉ trỏ được vào block cuối cùng.

Vì vậy, các block được cấp phát ban đầu sẽ không có pointer trỏ vào, và không thể free chúng được ⇨ Tiêu tốn cực nhiều bộ nhớ.

Kiểu này thường gặp nhưng cũng dễ để xử lý, bằng cách đưa hàm free() vào trong vòng lặp for.

💬 Ví dụ 2: Không giải phóng bộ nhớ khi gặp lỗi

char* getBlock(int fd) 
{
    char* buf = (char*) malloc(BLOCK_SIZE);
    if (!buf) 
    {
        return NULL;
    }
    if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) 
    {
        return NULL;
    }
    return buf;
}

Trên đây là một ví dụ đơn giản khác về Memory Leak. Hàm trên sẽ đọc một block nhớ mong muốn, nếu đọc được sẽ free vùng nhớ được phân bổ trong hàm.

Tuy nhiên, nếu hàm read() trả về sai số bytes mong muốn (BLOCK_SIZE) thì hàm sẽ trả về NULL, từ đó block nhớ đã malloc() trong hàm sẽ không được free() và gây ra Memory Leak.

Ngoài ra còn rất nhiều ví dụ khác về Memory Leak mà các bạn có thể tham khảo hoặc đã từng gặp phải 😆

👉 Kết luận và cách phòng tránh Memory Leak

Memory Leak là một vấn đề nghiêm trọng trong lập trình nhúng, có thể dẫn đến sự cố hệ thống và giảm hiệu suất. Để phòng tránh Memory Leak, các lập trình viên nhúng nên:

  • Luôn giải phóng bộ nhớ đã cấp phát khi không còn sử dụng.
  • Sử dụng các công cụ phân tích bộ nhớ để phát hiện Memory Leak.
  • Áp dụng các best practices trong quản lý bộ nhớ.
  • Thường xuyên review code và kiểm tra các trường hợp có thể gây ra Memory Leak.

>>>= Follow ngay để cập nhật thông tin mới nhất về lập trình nhúng =<<<

Để nhận được những bài học miễn phí mới nhất về lập trình nhúng và vi điều khiển nhé 😊

Chúc các bạn học tập tốt và thành công trong việc phát triển phần mềm nhúng 😊

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn