Gc vi trăn

def _make_html_response[bản thân, kết quả, lành mạnh]. cố gắng. tên máy chủ = ổ cắm. gethostname[] ngoại trừ ổ cắm. lỗi. tên máy chủ = Không có translate_results = [] cho kết quả trong kết quả. đã dịch_results. nối thêm [{ 'chi tiết'. kết quả. chi tiết hoặc '', 'lý do'. kết quả. lý do, 'lớp học'. sự phản xạ. get_class_name[result, full_qualified=False], }] params = { 'khỏe mạnh'. khỏe mạnh, 'tên máy chủ'. tên máy chủ, 'kết quả'. translate_results, 'chi tiết'. bản thân. _show_details, 'bây giờ'. str[thời gian sử dụng. utcnow[]], 'python_version'. hệ thống. phiên bản, 'nền tảng'. nền tảng. nền tảng[], 'gc'. { 'đếm'. gc. get_count[], 'ngưỡng'. gc. get_threshold[], }, 'chủ đề'. bản thân. _get_threadstacks[], 'luồng xanh'. bản thân. _get_threadstacks[], } body = _expand_template[self. HTML_RESPONSE_TEMPLATE, tham số] trả về [nội dung. dải[], 'văn bản/html']

Python là một trong những ngôn ngữ lập trình phổ biến nhất và việc sử dụng nó tiếp tục phát triển. Nó xếp thứ ba trong ngôn ngữ TIOBE của năm vào năm 2021 do tốc độ tăng trưởng của nó. Tính dễ sử dụng và cộng đồng lớn của Python đã khiến nó trở nên phổ biến để phân tích dữ liệu, ứng dụng web và tự động hóa tác vụ

Trong bài đăng này, chúng tôi sẽ đề cập chi tiết về thu gom rác trong Python. Đầu tiên, chúng ta sẽ xem lại những điều cơ bản về quản lý bộ nhớ và lý do tại sao chúng ta cần thu gom rác. Sau đó, chúng ta sẽ xem cách Python thực hiện thu gom rác. Cuối cùng, chúng ta sẽ có một cái nhìn thực tế về cách bạn nên nghĩ về thu gom rác khi viết các ứng dụng Python của mình

Bộ sưu tập rác Python là gì và tại sao chúng ta cần nó?

Nếu Python là ngôn ngữ lập trình đầu tiên của bạn, thì toàn bộ ý tưởng về thu gom rác có thể xa lạ với bạn. Hãy bắt đầu với những điều cơ bản

Quản lý bộ nhớ

Một ngôn ngữ lập trình sử dụng các đối tượng trong chương trình của nó để thực hiện các thao tác. Các đối tượng bao gồm các biến đơn giản, như chuỗi, số nguyên hoặc booleans. Chúng cũng bao gồm các cấu trúc dữ liệu phức tạp hơn như danh sách, hàm băm hoặc lớp

Các giá trị của các đối tượng chương trình của bạn được lưu trữ trong bộ nhớ để truy cập nhanh. Trong nhiều ngôn ngữ lập trình, một biến trong mã chương trình của bạn chỉ đơn giản là một con trỏ tới địa chỉ của đối tượng trong bộ nhớ. Khi một biến được sử dụng trong chương trình, tiến trình sẽ đọc giá trị từ bộ nhớ và thao tác trên biến đó

Trong các ngôn ngữ lập trình ban đầu, hầu hết các nhà phát triển chịu trách nhiệm quản lý bộ nhớ trong các chương trình của họ. Điều này có nghĩa là trước khi tạo một danh sách hoặc một đối tượng, trước tiên bạn cần cấp phát bộ nhớ cho biến của mình. Sau khi bạn đã hoàn thành với biến của mình, bạn cần giải phóng nó để “giải phóng” bộ nhớ đó cho những người dùng khác

Điều này dẫn đến hai vấn đề

  1. Quên giải phóng bộ nhớ của bạn. Nếu bạn không giải phóng bộ nhớ khi sử dụng xong, điều đó có thể dẫn đến rò rỉ bộ nhớ. Điều này có thể dẫn đến việc chương trình của bạn sử dụng quá nhiều bộ nhớ theo thời gian. Đối với các ứng dụng chạy lâu, điều này có thể gây ra sự cố nghiêm trọng
  2. Giải phóng bộ nhớ của bạn quá sớm. Loại vấn đề thứ hai bao gồm giải phóng bộ nhớ của bạn trong khi nó vẫn đang được sử dụng. Điều này có thể khiến chương trình của bạn gặp sự cố nếu chương trình cố truy cập vào một giá trị không tồn tại trong bộ nhớ hoặc có thể làm hỏng dữ liệu của bạn. Một biến đề cập đến bộ nhớ đã được giải phóng được gọi là con trỏ lơ lửng

Những sự cố này là không mong muốn nên các ngôn ngữ mới hơn đã thêm tính năng quản lý bộ nhớ tự động

Quản lý bộ nhớ tự động và thu gom rác

Với tính năng quản lý bộ nhớ tự động, các lập trình viên không còn cần phải tự quản lý bộ nhớ nữa. Thay vào đó, thời gian chạy đã xử lý việc này cho họ

Có một vài phương pháp khác nhau để quản lý bộ nhớ tự động. Những cái phổ biến sử dụng đếm tham chiếu. Với cách đếm tham chiếu, bộ thực thi theo dõi tất cả các tham chiếu đến một đối tượng. Khi một đối tượng không có tham chiếu đến nó, mã chương trình sẽ không sử dụng được và có thể bị xóa

Đối với các lập trình viên, quản lý bộ nhớ tự động bổ sung một số lợi ích. Phát triển chương trình nhanh hơn mà không cần suy nghĩ về chi tiết bộ nhớ cấp thấp. Hơn nữa, nó có thể giúp tránh rò rỉ bộ nhớ tốn kém hoặc con trỏ lơ lửng nguy hiểm

Tuy nhiên, quản lý bộ nhớ tự động có chi phí. Chương trình của bạn sẽ cần sử dụng thêm bộ nhớ và tính toán để theo dõi tất cả các tham chiếu của nó. Ngoài ra, nhiều ngôn ngữ lập trình có quản lý bộ nhớ tự động sử dụng quy trình “dừng thế giới” để thu gom rác khi tất cả quá trình thực thi dừng lại trong khi trình thu gom rác tìm kiếm và xóa các đối tượng cần thu thập

Với những tiến bộ trong quá trình xử lý máy tính từ định luật Moore và dung lượng RAM lớn hơn trong các máy tính mới hơn, lợi ích của việc quản lý bộ nhớ tự động thường lớn hơn những nhược điểm. Do đó, hầu hết các ngôn ngữ lập trình hiện đại như Java, Python và Golang đều sử dụng quản lý bộ nhớ tự động

Đối với các ứng dụng chạy lâu mà hiệu suất rất quan trọng, một số ngôn ngữ vẫn có quản lý bộ nhớ thủ công. Ví dụ kinh điển về điều này là C++. Chúng tôi cũng thấy quản lý bộ nhớ thủ công trong Objective-C, ngôn ngữ được sử dụng cho macOS và iOS. Đối với các ngôn ngữ mới hơn, Rust sử dụng quản lý bộ nhớ thủ công

Bây giờ chúng ta đã biết về quản lý bộ nhớ và thu gom rác nói chung, hãy tìm hiểu cụ thể hơn về cách hoạt động của bộ sưu tập rác Python

Hãy dùng thử Prefix, trình lược tả mã miễn phí của Stackify, để viết mã tốt hơn trên máy trạm của bạn. Tiền tố hoạt động với. NET, Java, PHP, Nút. js, Ruby và Python

Cách Python thực hiện thu gom rác

Trong phần này, chúng tôi sẽ đề cập đến cách hoạt động của bộ sưu tập rác trong Python

Phần này giả định rằng bạn đang sử dụng triển khai CPython của Python. CPython là triển khai được sử dụng rộng rãi nhất. Tuy nhiên, có các triển khai khác của Python, chẳng hạn như PyPy, Jython [dựa trên Java] hoặc IronPython [dựa trên C#]

Để xem bạn đang sử dụng Python nào, hãy chạy lệnh sau trong thiết bị đầu cuối của bạn [Linux]

>>>python -c 'import platform; print[platform.python_implementation[]]'

Or, you can have these lines for both Linux and Windows terminals.
>>> import platform
>>> print[platform.python_implementation[]]
CPython

Có hai khía cạnh để quản lý bộ nhớ và thu gom rác trong CPython

  • đếm tham chiếu
  • thu gom rác thế hệ

Hãy cùng khám phá từng điều dưới đây.  

Đếm tham chiếu trong CPython

Cơ chế thu gom rác chính trong CPython là thông qua. Bất cứ khi nào bạn tạo một đối tượng trong Python, đối tượng C bên dưới có cả loại Python [chẳng hạn như danh sách, dict hoặc hàm] và số lượng tham chiếu

Ở mức rất cơ bản, số lượng tham chiếu của đối tượng Python được tăng lên bất cứ khi nào đối tượng được tham chiếu và nó giảm đi khi một đối tượng bị hủy đăng ký. Nếu số lượng tham chiếu của một đối tượng là 0, bộ nhớ cho đối tượng sẽ bị giải phóng

Mã chương trình của bạn không thể tắt tính năng đếm tham chiếu của Python. Điều này trái ngược với trình thu gom rác thế hệ được thảo luận bên dưới

Một số người tuyên bố. Nó có một số nhược điểm, bao gồm không có khả năng phát hiện các tham chiếu theo chu kỳ như được thảo luận bên dưới. Tuy nhiên, việc đếm tham chiếu rất hay vì bạn có thể xóa ngay một đối tượng khi đối tượng đó không có tham chiếu

Xem số lượng tài liệu tham khảo trong Python

Bạn có thể sử dụng mô-đun sys từ thư viện chuẩn của Python để kiểm tra số lượng tham chiếu cho một đối tượng cụ thể. Có một số cách để tăng số lượng tham chiếu cho một đối tượng, chẳng hạn như

  • Gán một đối tượng cho một biến
  • Thêm đối tượng vào cấu trúc dữ liệu, chẳng hạn như thêm vào danh sách hoặc thêm dưới dạng thuộc tính trên thể hiện của lớp
  • Truyền đối tượng làm đối số cho hàm

Hãy sử dụng REPL của Python và mô-đun sys để xem cách xử lý số lượng tham chiếu

Trước tiên, trong thiết bị đầu cuối của bạn, hãy nhập python để vào một REPL của Python

Thứ hai, nhập mô-đun sys vào REPL của bạn. Sau đó, tạo một biến và kiểm tra số lượng tham chiếu của nó

>>> import sys
>>> a = 'my-string'
>>> sys.getrefcount[a]
2

Lưu ý rằng có hai tham chiếu đến biến của chúng ta a. Một là từ việc tạo biến. Thứ hai là khi chúng ta chuyển biến a cho sys. hàm getrefcount[]

Nếu bạn thêm biến vào cấu trúc dữ liệu, chẳng hạn như danh sách hoặc từ điển, thì bạn sẽ thấy số lượng tham chiếu tăng lên

>>> import sys
>>> a = 'my-string'
>>> b = [a] # Make a list with a as an element.
>>> c = { 'key': a } # Create a dictionary with a as one of the values.
>>> sys.getrefcount[a]
4

Như đã trình bày ở trên, số lượng tham chiếu của a tăng khi được thêm vào danh sách hoặc từ điển

Trong phần tiếp theo, chúng ta sẽ tìm hiểu về bộ thu gom rác thế hệ, đây là công cụ thứ hai mà Python sử dụng để quản lý bộ nhớ

thu gom rác thế hệ

Ngoài chiến lược đếm tham chiếu để quản lý bộ nhớ, Python còn sử dụng một phương thức gọi là bộ thu gom rác thế hệ

Cách dễ nhất để hiểu tại sao chúng ta cần một bộ thu gom rác thế hệ là lấy ví dụ

Trong phần trước, chúng ta đã thấy rằng việc thêm một đối tượng vào một mảng hoặc đối tượng sẽ làm tăng số lượng tham chiếu của nó. Nhưng điều gì sẽ xảy ra nếu bạn thêm một đối tượng vào chính nó?

>>> class MyClass[object]:
..     pass
...
>>> a = MyClass[]
>>> a.obj = a
>>> del a

Trong ví dụ trên, chúng ta đã định nghĩa một lớp mới. Sau đó, chúng tôi đã tạo một thể hiện của lớp và gán thể hiện đó là một thuộc tính trên chính nó. Cuối cùng, chúng tôi đã xóa ví dụ

Bằng cách xóa phiên bản, nó không còn truy cập được trong chương trình Python của chúng tôi. Tuy nhiên, Python không hủy instance khỏi bộ nhớ. Phiên bản không có số tham chiếu bằng 0 vì nó có tham chiếu đến chính nó

Chúng tôi gọi loại vấn đề này là chu trình tham chiếu và bạn không thể giải nó bằng cách đếm tham chiếu. Đây là điểm của trình thu gom rác thế hệ mà mô-đun gc có thể truy cập được trong thư viện chuẩn

Thuật ngữ thu gom rác thế hệ

Có hai khái niệm chính cần hiểu với trình thu gom rác thế hệ

  1. Khái niệm đầu tiên là của một thế hệ
  2. Khái niệm quan trọng thứ hai là ngưỡng.  

Trình thu gom rác đang theo dõi tất cả các đối tượng trong bộ nhớ. Một đối tượng mới bắt đầu cuộc sống của nó trong thế hệ đầu tiên của trình thu gom rác. Nếu Python thực thi quy trình thu gom rác trên một thế hệ và một đối tượng vẫn tồn tại, thì nó sẽ chuyển sang thế hệ thứ hai, cũ hơn. Trình thu gom rác Python có tổng cộng ba thế hệ và một đối tượng sẽ chuyển sang thế hệ cũ hơn bất cứ khi nào nó tồn tại trong quy trình thu gom rác trên thế hệ hiện tại của nó

Đối với mỗi thế hệ, mô-đun thu gom rác có một số đối tượng ngưỡng. Nếu số lượng đối tượng vượt quá ngưỡng đó, trình thu gom rác sẽ kích hoạt quy trình thu thập. Đối với bất kỳ đối tượng nào tồn tại trong quá trình đó, chúng sẽ được chuyển sang thế hệ cũ hơn

Không giống như cơ chế đếm tham chiếu, bạn có thể thay đổi hành vi của trình thu gom rác thế hệ trong chương trình Python của mình. Điều này bao gồm việc thay đổi ngưỡng kích hoạt quy trình thu gom rác trong mã của bạn. Ngoài ra, bạn có thể kích hoạt quy trình thu gom rác theo cách thủ công hoặc tắt hoàn toàn quy trình thu gom rác

Hãy xem cách bạn có thể sử dụng mô-đun gc để kiểm tra số liệu thống kê về bộ sưu tập rác hoặc thay đổi hành vi của bộ thu gom rác

Sử dụng mô-đun GC

Trong thiết bị đầu cuối của bạn, hãy nhập python để truy cập REPL của Python

Nhập mô-đun gc vào phiên của bạn. Sau đó, bạn có thể kiểm tra các ngưỡng đã định cấu hình của trình thu gom rác bằng phương thức get_threshold[] 

>>> import gc
>>> gc.get_threshold[]
[700, 10, 10]

Theo mặc định, Python có ngưỡng 700 cho thế hệ trẻ nhất và 10 cho mỗi thế hệ trong số hai thế hệ cũ

Bạn có thể kiểm tra số lượng đối tượng trong mỗi thế hệ của mình bằng phương thức get_count[] 

>>> import gc
>>> gc.get_count[]
[596, 2, 1]

Trong ví dụ này, chúng tôi có 596 đối tượng ở thế hệ trẻ nhất, hai đối tượng ở thế hệ tiếp theo và một đối tượng ở thế hệ cũ nhất

Như bạn có thể thấy, Python tạo một số đối tượng theo mặc định trước khi bạn bắt đầu thực hiện chương trình của mình. Bạn có thể kích hoạt quy trình thu gom rác thủ công bằng cách sử dụng lệnh gc. phương thức thu thập[]

>>> gc.get_count[]
[595, 2, 1]
>>> gc.collect[]
577
>>> gc.get_count[]
[18, 0, 0]

Chạy quy trình thu gom rác sẽ dọn sạch một lượng lớn đối tượng—có 577 đối tượng trong thế hệ đầu tiên và ba đối tượng nữa trong các thế hệ cũ hơn

Bạn có thể thay đổi ngưỡng kích hoạt thu gom rác bằng cách sử dụng phương thức set_threshold[] trong mô-đun gc

>>> import gc
>>> gc.get_threshold[]
[700, 10, 10]
>>> gc.set_threshold[1000, 15, 15]
>>> gc.get_threshold[]
[1000, 15, 15]

Trong ví dụ trên, chúng tôi tăng từng ngưỡng của mình từ giá trị mặc định của chúng. Tăng ngưỡng sẽ giảm tần suất chạy bộ thu gom rác. Điều này sẽ ít tốn kém hơn về mặt tính toán trong chương trình của bạn với chi phí giữ các đối tượng chết lâu hơn

Bây giờ bạn đã biết cách hoạt động của cả mô-đun đếm tham chiếu và mô-đun thu gom rác, hãy thảo luận về cách bạn nên sử dụng mô-đun này khi viết các ứng dụng Python

Trình thu gom rác của Python có ý nghĩa gì đối với bạn với tư cách là nhà phát triển

Chúng ta đã dành khá nhiều thời gian để thảo luận về quản lý bộ nhớ nói chung và việc triển khai nó trong Python. Bây giờ là lúc để làm cho nó hữu ích. Bạn nên sử dụng thông tin này như thế nào với tư cách là nhà phát triển chương trình Python?

Nguyên tắc chung. Không thay đổi hành vi thu gom rác

Theo nguyên tắc chung, có lẽ bạn không nên nghĩ quá nhiều về bộ sưu tập rác của Python. Một trong những lợi ích chính của Python là nó cho phép năng suất của nhà phát triển. Một phần lý do cho điều này là vì đây là ngôn ngữ cấp cao xử lý một số chi tiết cấp thấp cho nhà phát triển

Quản lý bộ nhớ thủ công phù hợp hơn với các môi trường bị hạn chế. Nếu bạn thấy mình có những hạn chế về hiệu suất mà bạn cho rằng có thể liên quan đến cơ chế thu gom rác của Python, thì việc tăng sức mạnh cho môi trường thực thi của bạn có thể sẽ hữu ích hơn thay vì thay đổi quy trình thu gom rác theo cách thủ công. Trong một thế giới của định luật Moore, điện toán đám mây và bộ nhớ rẻ, nhiều năng lượng hơn có thể dễ dàng tiếp cận

Điều này thậm chí còn thực tế vì Python thường không giải phóng bộ nhớ trở lại hệ điều hành cơ bản. Bất kỳ quy trình thu gom rác thủ công nào bạn thực hiện để giải phóng bộ nhớ có thể không mang lại cho bạn kết quả như mong muốn. Để biết thêm chi tiết về lĩnh vực này, hãy tham khảo bài đăng này về quản lý bộ nhớ trong Python

Vô hiệu hóa bộ thu gom rác

Với cảnh báo đó sang một bên, có những tình huống mà bạn có thể muốn quản lý quy trình thu gom rác. Hãy nhớ rằng không thể tắt tính năng đếm tham chiếu, cơ chế thu gom rác chính trong Python. Hành vi thu gom rác duy nhất mà bạn có thể thay đổi là trình thu gom rác thế hệ trong mô-đun gc

Một trong những ví dụ thú vị hơn về việc thay đổi trình thu gom rác thế hệ đến từ việc Instagram vô hiệu hóa hoàn toàn trình thu gom rác

Instagram sử dụng Django, khung web Python phổ biến, cho các ứng dụng web của mình. Nó chạy nhiều phiên bản của ứng dụng web trên một phiên bản điện toán duy nhất. Các phiên bản này được chạy bằng cơ chế chính-con trong đó các tiến trình con chia sẻ bộ nhớ với chủ

Nhóm nhà phát triển Instagram nhận thấy rằng bộ nhớ dùng chung sẽ giảm mạnh ngay sau khi một tiến trình con sinh ra. Khi đào sâu hơn, họ thấy rằng người thu gom rác là nguyên nhân

Nhóm Instagram đã vô hiệu hóa mô-đun thu gom rác bằng cách đặt ngưỡng cho tất cả các thế hệ thành 0. Thay đổi này giúp các ứng dụng web của họ chạy hiệu quả hơn 10%

Mặc dù ví dụ này rất thú vị, nhưng hãy chắc chắn rằng bạn đang ở trong tình huống tương tự trước khi đi theo con đường tương tự. Instagram là một ứng dụng quy mô web phục vụ hàng triệu người dùng. Đối với họ, thật đáng để sử dụng một số hành vi không chuẩn để vắt kiệt từng inch hiệu suất từ ​​các ứng dụng web của họ. Đối với hầu hết các nhà phát triển, hành vi tiêu chuẩn của Python xung quanh việc thu gom rác là đủ

Nếu bạn nghĩ rằng bạn có thể muốn quản lý bộ sưu tập rác theo cách thủ công trong Python, trước tiên hãy đảm bảo rằng bạn hiểu vấn đề. Sử dụng các công cụ như Stackify's Retrace để đo hiệu suất ứng dụng của bạn và xác định chính xác các vấn đề. Khi bạn hoàn toàn hiểu vấn đề, sau đó thực hiện các bước để khắc phục sự cố

Bắt đầu dùng thử MIỄN PHÍ 14 ngày của bạn ngay hôm nay

kết thúc

Trong bài đăng này, chúng ta đã tìm hiểu về bộ sưu tập rác Python. Chúng tôi bắt đầu bằng cách trình bày những điều cơ bản về quản lý bộ nhớ và tạo quản lý bộ nhớ tự động. Sau đó, chúng tôi đã xem xét cách triển khai bộ sưu tập rác trong Python, thông qua cả việc đếm tham chiếu tự động và trình thu gom rác thế hệ. Cuối cùng, chúng tôi đã xem xét điều này quan trọng như thế nào đối với bạn với tư cách là nhà phát triển Python

Mặc dù Python xử lý hầu hết các phần khó của quản lý bộ nhớ cho bạn, nhưng vẫn rất hữu ích khi biết điều gì đang xảy ra bên trong. Từ việc đọc bài đăng này, bây giờ bạn biết rằng bạn nên tránh các chu kỳ tham chiếu trong Python và bạn nên biết nơi để tìm nếu bạn cần kiểm soát tốt hơn đối với trình thu gom rác Python

GC hoạt động như thế nào trong Python?

Nếu Python thực thi quy trình thu gom rác trên một thế hệ và một đối tượng vẫn tồn tại, thì nó sẽ chuyển sang thế hệ thứ hai, cũ hơn . Trình thu gom rác Python có tổng cộng ba thế hệ và một đối tượng sẽ chuyển sang thế hệ cũ hơn bất cứ khi nào nó tồn tại trong quy trình thu gom rác trên thế hệ hiện tại của nó.

Python có bộ sưu tập rác không?

Quá trình mà Python định kỳ giải phóng và thu hồi các khối bộ nhớ không còn được sử dụng nữa được gọi là Garbage Collection. Trình thu gom rác của Python chạy trong khi thực thi chương trình và được kích hoạt khi số tham chiếu của đối tượng bằng 0

GC thu thập[] trả về cái gì?

Buộc thu gom rác . the number of “unreachable” objects it found.

GC thu thập trong C# là gì?

Nó thực hiện chặn thu gom rác của tất cả các thế hệ . Tất cả các đối tượng, bất kể chúng đã ở trong bộ nhớ bao lâu, đều được xem xét để thu thập; . Sử dụng phương pháp này để buộc hệ thống cố gắng lấy lại dung lượng bộ nhớ khả dụng tối đa.

Chủ Đề