Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Cách tạo rò rỉ bộ nhớ (Memory Leak) trong Ruby một cách có chủ đích – Minh họa thực tế

Có một vài bài viết về cách tìm rò rỉ bộ nhớ.

Nhưng làm thế nào để tạo ra một?

Tôi nghĩ đây sẽ là bài tập thú vị để bạn biết rò rỉ bộ nhớ trông như thế nào trong Ruby.

Hãy xem một số ví dụ.

Một rò rỉ đơn giản

Chúng ta có thể tạo rò rỉ bộ nhớ bằng cách đơn giản là thêm đối tượng mới vào một mảng.

Như sau:

a = []
b = {}
loop { sleep(1)
  10_000.times { a << "abc" }
  puts GC.stat(b)[:heap_live_slots]
}

Điều này tạo ra 10k chuỗi mỗi giây & in ra số lượng đối tượng:

285051
295052
305053
315054
325055
335056
345057
355058

Số lượng cứ tăng lên vì GC không thể thu gom các chuỗi này, chúng đang được tham chiếu bởi mảng chứa (a).

Nếu a ra khỏi phạm vi (scope) điều đó sẽ cho phép GC thu gom tất cả các chuỗi "abc" này. Bạn có thể kiểm tra với ví dụ trên bằng cách đặt a thành nil, sau đó chạy GC.start.

Bạn có thể tìm thấy ví dụ trực tiếp tại đây, chỉ cần bấm run để xem kết quả.

Rò rỉ C Extension

Khi bạn tạo đối tượng từ Ruby, GC theo dõi lượng bộ nhớ nó sử dụng, nhưng khi dùng C extension Ruby không có kiểm soát gì.

Nếu bạn tạo C extension như sau:

#include <ruby.h>
#include "extconf.h"
void *ptr;
void Init_extension() {
  allocate_memory();
}
void allocate_memory() {
  for(int i = 0; i < 10000; i++) {
    ptr = malloc(1000);
  }
}

Hàm allocate_memory() sẽ rò rỉ bộ nhớ vì nó dùng malloc & không gọi free để giải phóng bộ nhớ đó.

Như bạn thấy ở đây:

`ps -o rss -p #{$$}`.lines.last # "49036"
require './extension'
`ps -o rss -p #{$$}`.lines.last # "89512"

Loại rò rỉ này sẽ không xuất hiện trên bất kỳ heap dump nào hoặc trên GC.stat, nhưng bạn sẽ thấy sử dụng bộ nhớ tăng lên.

Tóm tắt

Bây giờ bạn biết rò rỉ bộ nhớ trông như thế nào, hy vọng điều đó sẽ giúp bạn tìm thấy nó nhanh hơn nếu bạn bao giờ gặp vấn đề này. Btw Ruby 2.4.1 có rò rỉ bộ nhớ đã biết, vì vậy bạn có thể muốn nâng cấp nếu bạn đang dùng phiên bản cụ thể này.

Bạn có câu hỏi, phản hồi hoặc câu chuyện debug rò rỉ bộ nhớ thú vị? Để lại bình luận bên dưới 🙂

Cảm ơn bạn đã đọc!