Hãy xem câu trả lời tiếp theo bởi @joeblog cho các giải pháp tốt hơn.
Trước tiên, bạn không cần tất cả RAM đó ngay từ đầu. Những gì bạn nên làm ở đây là tìm nạp khối của tập hợp kết quả. Đừng làm một số fetchall()
. Thay vào đó, hãy sử dụng phương thức cursor.fetchmany
hiệu quả hơn nhiều. Xem the psycopg2 documentation.
Bây giờ, lời giải thích cho lý do tại sao nó không được trả tự do, và lý do tại sao đó không phải là một rò rỉ bộ nhớ trong việc sử dụng chính thức đúng đắn về thuật ngữ đó.
Hầu hết các quá trình không giải phóng bộ nhớ trở lại hệ điều hành khi nó được giải phóng, họ chỉ làm cho nó có sẵn để tái sử dụng ở những nơi khác trong chương trình.
Memory chỉ có thể được phát hành cho hệ điều hành nếu chương trình có thể nhỏ gọn các đối tượng còn lại nằm rải rác trong bộ nhớ. Điều này chỉ có thể nếu các tham chiếu xử lý gián tiếp được sử dụng, vì nếu không di chuyển một đối tượng sẽ làm mất hiệu lực các con trỏ hiện có đối với đối tượng. Tài liệu tham khảo gián tiếp là khá kém hiệu quả, đặc biệt là trên các CPU hiện đại, nơi các con trỏ tìm kiếm xung quanh thực hiện những điều kinh khủng.
Điều gì thường xảy ra khi không có sự chú ý của chương trình là mỗi đoạn bộ nhớ lớn được phân bổ với brk()
đáp ứng một vài phần nhỏ vẫn đang được sử dụng.
Hệ điều hành không thể nói cho dù chương trình xem xét bộ nhớ này vẫn được sử dụng hay không, vì vậy nó không thể chỉ tuyên bố nó trở lại. Vì chương trình không có xu hướng truy cập vào bộ nhớ nên hệ điều hành thường sẽ hoán đổi nó theo thời gian, giải phóng bộ nhớ vật lý cho các ứng dụng khác. Đây là một trong những lý do bạn nên có không gian trao đổi.
Có thể viết chương trình mà tay bộ nhớ trở lại hệ điều hành, nhưng tôi không chắc chắn rằng bạn có thể làm điều đó với Python.
Xem thêm:
Vì vậy: đây không phải là thực sự là một bộ nhớ bị rò rỉ . Nếu bạn làm điều gì đó khác sử dụng rất nhiều bộ nhớ, quá trình này sẽ không phát triển nhiều nếu ở tất cả, nó sẽ tái sử dụng bộ nhớ giải phóng trước đó từ phân bổ lớn cuối cùng.
Nguồn
2013-06-20 01:20:53
Cảm ơn! Xác nhận rằng bộ nhớ được tái sử dụng bằng cách chạy mã trên hai lần trong cùng một quá trình. Bộ nhớ không tăng trong lần chạy thứ hai. –
Trong khi tất cả mọi thứ nói ở đây là đúng, một kết quả truy vấn bình thường sẽ được chuyển hoàn toàn trên phía máy khách (không phải bởi 'fetch *()' mà bởi 'execute()'). Vì vậy, trong khi sử dụng 'fetchmany()' thay vì 'fetchall()' có thể tiết kiệm một số bộ nhớ về tạo đối tượng Python, sử dụng con trỏ phía máy chủ như được đề xuất bởi @joeblog là giải pháp đúng. – piro