Có nên xóa ironpython trong ổ window
Ngay cả tôi cũng gặp vấn đề tương tự khi hiểu CPython, JPython, IronPython, PyPy khác nhau như thế nào. Show Vì vậy, tôi sẵn sàng làm rõ ba điều trước khi bắt đầu giải thích:
Nếu bạn muốn xem mã byte của CPython thì bạn có thể. Đây là cách bạn có thể:
Bây giờ, chúng ta hãy xem mã trên. Dòng 1 đến 6 là một định nghĩa hàm. Trong dòng 8, chúng tôi nhập mô-đun 'dis' có thể được sử dụng để xem mã byte trung gian Python (hoặc bạn có thể nói, trình dịch ngược mã cho mã byte Python) được tạo bởi CPython (trình thông dịch). LƯU Ý: Tôi đã nhận được liên kết tới mã này từ #python IRC kênh: https://Gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c Và sau đó, có Jython, được viết bằng Java và cuối cùng tạo ra mã byte Java. Mã byte Java chạy trên Môi trường chạy thi hành Java, là một triển khai của Máy ảo Java (JVM). Nếu điều này gây nhầm lẫn thì tôi nghi ngờ rằng bạn không biết Java hoạt động như thế nào. Theo thuật ngữ layman, mã Java (ngôn ngữ, không phải trình biên dịch) được trình biên dịch Java lấy và xuất ra một tệp (là mã byte Java) chỉ có thể chạy bằng JRE. Điều này được thực hiện sao cho, khi mã Java được biên dịch thì nó có thể được chuyển sang các máy khác ở định dạng mã byte Java, chỉ có thể được chạy bởi JRE. Nếu điều này vẫn còn khó hiểu thì bạn có thể muốn xem cái này trang web . Ở đây, bạn có thể hỏi liệu mã byte của CPython có di động như Jython không, tôi nghi ngờ là không. Bytecode được tạo ra trong triển khai CPython dành riêng cho trình thông dịch đó để giúp dễ dàng thực thi mã hơn (Tôi cũng nghi ngờ rằng, việc sản xuất mã byte trung gian như vậy, chỉ để dễ dàng xử lý được thực hiện trong nhiều trình thông dịch khác). Vì vậy, trong Jython, khi bạn biên dịch mã Python, bạn kết thúc bằng mã byte Java, có thể chạy trên JVM. Tương tự, IronPython (viết bằng ngôn ngữ C #) biên dịch mã Python của bạn thành Common Language Runtime (CLR), đây là một công nghệ tương tự như so với JVM, được phát triển bởi Microsoft. Mục lục bài viết:
Bạn đã bao giờ tự hỏi làm thế nào Python xử lý dữ liệu của bạn đằng sau hậu trường? Làm thế nào các biến của bạn được lưu trữ trong bộ nhớ? Khi nào chúng bị xóa? Trong bài viết này, chúng ta sẽ đi sâu vào bên trong của Python để hiểu cách nó xử lý việc quản lý bộ nhớ. Đến cuối bài viết này, bạn sẽ:
Tìm hiểu nội bộ của Python cũng sẽ cung cấp cho bạn cái nhìn sâu sắc hơn về một số hành vi của Python. Hy vọng rằng bạn cũng sẽ có được một sự đánh giá cao mới đối với Python. Rất nhiều logic đang diễn ra đằng sau hậu trường để đảm bảo chương trình của bạn hoạt động theo cách bạn mong đợi. Trí nhớ là một cuốn sách trốngBạn có thể bắt đầu bằng cách coi bộ nhớ của máy tính như một cuốn sách trống dành cho truyện ngắn. Chưa có gì được viết trên các trang. Cuối cùng, các tác giả khác nhau sẽ xuất hiện. Mỗi tác giả muốn một số không gian để viết câu chuyện của họ. Vì họ không được phép viết chồng lên nhau, họ phải cẩn thận xem mình viết ở trang nào. Trước khi bắt đầu viết, họ hỏi ý kiến của người quản lý cuốn sách. Sau đó, người quản lý quyết định họ được phép viết ở đâu trong cuốn sách. Vì cuốn sách này ra đời đã lâu nên nhiều câu chuyện trong đó không còn phù hợp nữa. Khi không có ai đọc hoặc tham khảo các câu chuyện, chúng sẽ bị loại bỏ để nhường chỗ cho các câu chuyện mới. Về bản chất, bộ nhớ máy tính giống như một cuốn sách trống đó. Trên thực tế, người ta thường gọi các khối trang bộ nhớ liền kề có độ dài cố định , vì vậy sự tương tự này khá tốt. Các tác giả giống như các ứng dụng hoặc quy trình khác nhau cần lưu trữ dữ liệu trong bộ nhớ. Người quản lý, người quyết định nơi tác giả có thể viết trong sách, đóng vai trò là người quản lý bộ nhớ. Người dẹp bỏ những câu chuyện cũ để nhường chỗ cho những câu chuyện mới là một người thu gom rác. Quản lý bộ nhớ: Từ phần cứng đến phần mềmQuản lý bộ nhớ là quá trình ứng dụng đọc và ghi dữ liệu . Trình quản lý bộ nhớ xác định vị trí đặt dữ liệu của ứng dụng. Vì có một phần bộ nhớ hữu hạn, giống như các trang trong cuốn sách tương tự của chúng tôi, người quản lý phải tìm một số không gian trống và cung cấp nó cho ứng dụng. Quá trình này cung cấp bộ nhớ thường được gọi là bộ nhớ phân bổ . Mặt khác, khi dữ liệu không còn cần thiết nữa, nó có thể bị xóa hoặc giải phóng . Nhưng giải thoát đến đâu? “Ký ức” này đến từ đâu? Ở đâu đó trong máy tính của bạn, có một thiết bị vật lý lưu trữ dữ liệu khi bạn đang chạy các chương trình Python của mình. Tuy nhiên, có nhiều lớp trừu tượng mà mã Python phải trải qua trước khi các đối tượng thực sự truy cập vào phần cứng. Một trong những lớp chính bên trên phần cứng (chẳng hạn như RAM hoặc ổ cứng) là hệ điều hành (OS). Nó thực hiện (hoặc từ chối) các yêu cầu đọc và ghi bộ nhớ. Bên trên hệ điều hành, có các ứng dụng, một trong số đó là triển khai Python mặc định (được bao gồm trong hệ điều hành của bạn hoặc tải xuống từ python.org .) Việc quản lý bộ nhớ cho mã Python của bạn được ứng dụng Python xử lý. Các thuật toán và cấu trúc mà ứng dụng Python sử dụng để quản lý bộ nhớ là trọng tâm của bài viết này. Triển khai Python mặc địnhGiá trị mặc định thực hiện Python, CPython , thực sự được viết trong ngôn ngữ lập trình C . Khi tôi lần đầu tiên nghe thấy điều này, nó đã thổi bay tâm trí của tôi. Một ngôn ngữ được viết bằng một ngôn ngữ khác ?! Chà, không hẳn, nhưng đại loại là vậy. Ngôn ngữ Python được định nghĩa trong sổ tay tham khảo được viết bằng tiếng Anh. Tuy nhiên, bản thân sách hướng dẫn đó không phải là tất cả những gì hữu ích. Bạn vẫn cần một cái gì đó để giải thích mã đã viết dựa trên các quy tắc trong sách hướng dẫn. Bạn cũng cần một cái gì đó để thực thi mã được thông dịch trên máy tính. Việc triển khai Python mặc định đáp ứng cả hai yêu cầu đó. Nó chuyển đổi mã Python của bạn thành các hướng dẫn để sau đó chạy trên máy ảo. Lưu ý: Máy ảo giống như máy tính vật lý, nhưng chúng được thực hiện trong phần mềm. Chúng thường xử lý các hướng dẫn cơ bản tương tự như hướng dẫn Assembly . Python là một ngôn ngữ lập trình thông dịch. Mã Python của bạn thực sự được biên dịch thành các hướng dẫn máy tính dễ đọc hơn được gọi là bytecode . Các hướng dẫn này được máy ảo thông dịch khi bạn chạy mã của mình. Bạn đã bao giờ nhìn thấy một Điều quan trọng cần lưu ý là có những triển khai khác ngoài CPython. IronPython biên dịch xuống để chạy trên Thời gian chạy ngôn ngữ chung của Microsoft. Jython biên dịch thành mã bytecode của Java để chạy trên Máy ảo Java. Sau đó, có PyPy , nhưng điều đó xứng đáng với toàn bộ bài viết của riêng nó , vì vậy tôi sẽ chỉ đề cập đến nó. Với mục đích của bài viết này, tôi sẽ tập trung vào việc quản lý bộ nhớ được thực hiện bằng cách triển khai mặc định của Python, CPython. Tuyên bố từ chối trách nhiệm : Mặc dù rất nhiều thông tin này sẽ được chuyển sang các phiên bản Python mới, nhưng mọi thứ có thể thay đổi trong tương lai. Lưu ý rằng phiên bản được tham chiếu cho
bài viết này là phiên bản Python mới nhất hiện tại , Được rồi, vì vậy CPython được viết bằng C và nó diễn giải mã bytecode của Python. Điều này có liên quan gì đến quản lý bộ nhớ? Vâng, các thuật toán và cấu trúc quản lý bộ nhớ tồn tại trong mã CPython, trong C. Để hiểu việc quản lý bộ nhớ của Python, bạn phải hiểu cơ bản về chính CPython. CPython được viết bằng C, không hỗ trợ lập trình hướng đối tượng . Do đó, có khá nhiều thiết kế thú vị trong mã CPython. Bạn có thể đã nghe nói rằng mọi thứ trong Python đều là một đối tượng, ngay cả các loại như Lưu ý: A Ông
Số lượng tham chiếu được sử dụng để thu gom rác. Sau đó, bạn có một con trỏ đến kiểu đối tượng thực tế. Kiểu đối tượng đó chỉ là một kiểu khác Mỗi đối tượng có bộ cấp phát bộ nhớ dành riêng cho đối tượng của riêng nó biết cách lấy bộ nhớ để lưu đối tượng đó. Mỗi đối tượng cũng có một bộ phân bổ bộ nhớ dành riêng cho đối tượng để “giải phóng” bộ nhớ khi nó không còn cần thiết nữa. Tuy nhiên, có một yếu tố quan trọng trong tất cả những gì nói về việc phân bổ và giải phóng bộ nhớ. Bộ nhớ là tài nguyên được chia sẻ trên máy tính và những điều tồi tệ có thể xảy ra nếu hai tiến trình khác nhau cố gắng ghi vào cùng một vị trí cùng một lúc. Khóa thông dịch viên toàn cầu (GIL)GIL là một giải pháp cho vấn đề chung về xử lý tài nguyên được chia sẻ, chẳng hạn như bộ nhớ trong máy tính. Khi hai luồng cố gắng sửa đổi cùng một tài nguyên cùng một lúc, chúng có thể giẫm lên nhau. Kết quả cuối cùng có thể là một mớ hỗn độn bị cắt xén mà cả hai chủ đề đều không kết thúc với những gì họ muốn. Hãy xem xét sự tương tự cuốn sách một lần nữa. Giả sử rằng hai tác giả ngoan cố quyết định rằng đến lượt họ viết. Không chỉ vậy, cả hai đều cần phải viết trên cùng một trang của cuốn sách cùng một lúc. Họ bỏ qua nỗ lực của người kia để tạo ra một câu chuyện và bắt đầu viết trên trang. Kết quả cuối cùng là hai câu chuyện chồng lên nhau, khiến toàn bộ trang không thể đọc được. Một giải pháp cho vấn đề này là một khóa chung, duy nhất trên trình thông dịch khi một luồng tương tác với tài nguyên được chia sẻ (trang trong sách). Nói cách khác, chỉ một tác giả có thể viết tại một thời điểm. GIL của Python thực hiện được điều này bằng cách khóa toàn bộ trình thông dịch, có nghĩa là không thể để một luồng khác dẫm lên luồng hiện tại. Khi CPython xử lý bộ nhớ, nó sử dụng GIL để đảm bảo rằng nó hoạt động một cách an toàn. Có những ưu và nhược điểm đối với cách tiếp cận này và GIL được tranh luận rất nhiều trong cộng đồng Python. Để đọc thêm về GIL, tôi khuyên bạn nên xem Khóa thông dịch viên toàn cầu Python (GIL) là gì? . Thu gom rácHãy xem lại sự tương tự cuốn sách và giả định rằng một số câu chuyện trong cuốn sách đang trở nên rất cũ. Không ai đang đọc hoặc tham khảo những câu chuyện đó nữa. Nếu không có ai đang đọc cái gì đó hoặc tham khảo nó trong tác phẩm của riêng họ, bạn có thể loại bỏ nó để nhường chỗ cho bài viết mới. Văn bản cũ, không được tham chiếu đó có thể được so sánh với một đối tượng trong Python có số lượng tham chiếu đã giảm xuống Số lượng tham chiếu được tăng lên vì một vài lý do khác nhau. Ví dụ: số lượng tham chiếu sẽ tăng lên nếu bạn gán nó cho một biến khác:
Nó cũng sẽ tăng lên nếu bạn truyền đối tượng làm đối số: Ví dụ cuối cùng, số lượng tham chiếu sẽ tăng lên nếu bạn đưa đối tượng vào danh sách:
Python cho phép bạn kiểm tra số lượng tham chiếu hiện tại của một đối tượng với Trong mọi trường
hợp, nếu đối tượng vẫn được yêu cầu lưu lại trong mã của bạn, thì số lượng tham chiếu của nó lớn hơn Nhưng “giải phóng” bộ nhớ có nghĩa là gì và các đối tượng khác sử dụng nó như thế nào? Hãy bắt tay ngay vào quản lý bộ nhớ của CPython. Quản lý bộ nhớ của CPythonChúng ta sẽ đi sâu vào kiến trúc bộ nhớ và các thuật toán của CPython, vì vậy hãy thắt dây an toàn. Như đã đề cập trước đây, có nhiều lớp trừu tượng từ phần cứng vật lý đến CPython. Hệ điều hành (OS) trừu tượng hóa bộ nhớ vật lý và tạo một lớp bộ nhớ ảo mà các ứng dụng (bao gồm cả Python) có thể truy cập. Trình quản lý bộ nhớ ảo dành riêng cho hệ điều hành tạo ra một phần bộ nhớ cho quy trình Python. Các hộp màu xám đậm hơn trong hình ảnh bên dưới hiện thuộc sở hữu của quy trình Python. Python sử dụng một phần bộ nhớ để sử dụng nội bộ và bộ nhớ
không phải đối tượng. Phần khác là dành riêng cho lưu trữ đối tượng (của bạn CPython có một bộ cấp phát đối tượng chịu trách nhiệm cấp phát bộ nhớ trong vùng bộ nhớ đối tượng. Bộ phân bổ đối tượng này là nơi hầu hết các điều kỳ diệu xảy ra. Nó được gọi mỗi khi một đối tượng mới cần được cấp phát hoặc xóa không gian. Thông thường, việc thêm và xóa dữ liệu cho các đối tượng Python như Các chú thích trong mã nguồn mô tả trình cấp phát là “một trình cấp phát bộ nhớ nhanh, có mục đích đặc biệt cho các khối nhỏ, được sử dụng trên đầu của một malloc có mục đích chung”. Trong trường hợp này, Bây giờ chúng ta sẽ xem xét chiến lược phân bổ bộ nhớ của CPython. Đầu tiên, chúng ta sẽ nói về 3 phần chính và cách chúng liên quan với nhau. Các khu vực là phần lớn nhất của bộ nhớ và được căn chỉnh trên một ranh giới trang trong bộ nhớ. Ranh giới trang là cạnh của đoạn bộ nhớ liền kề có độ dài cố định mà Hệ điều hành sử dụng. Python giả định kích thước trang của hệ thống là 256 kilobyte. Trong đấu trường là các nhóm, là một trang bộ nhớ ảo (4 kilobyte). Đây giống như các trang trong cuốn sách tương tự của chúng tôi. Các nhóm này được phân mảnh thành các khối bộ nhớ nhỏ hơn. Tất cả các khối trong một nhóm nhất định đều có cùng “loại kích thước”. Một lớp kích thước xác định một kích thước khối cụ thể, với một số lượng dữ liệu được yêu cầu. Biểu đồ dưới đây được lấy trực tiếp từ các bình luận mã nguồn :
Ví dụ: nếu 42 byte được yêu cầu, dữ liệu sẽ được đặt vào một khối kích thước 48 byte. Hồ bơiHồ bơi bao gồm các khối từ một lớp kích thước duy nhất. Mỗi nhóm duy trì một danh sách liên kết kép với các nhóm khác có cùng loại kích thước. Bằng cách đó, thuật toán có thể dễ dàng tìm thấy không gian có sẵn cho một kích thước khối nhất định, thậm chí trên các nhóm khác nhau. Một Hồ mình phải nằm trong một trong 3 trạng thái: Một Giả sử mã của bạn cần một đoạn bộ nhớ 8 byte. Nếu
không có nhóm nào trong Giả sử một Bây giờ bạn có thể thấy cách các nhóm có thể di chuyển giữa các trạng thái này (và thậm chí các lớp kích thước bộ nhớ) một cách tự do với thuật toán này. KhốiNhư đã thấy trong sơ đồ trên, các nhóm chứa một con trỏ đến các khối bộ nhớ “miễn phí” của chúng. Có một chút sắc thái đối với cách thức hoạt động của nó. Bộ phân bổ này “cố gắng ở tất cả các cấp (đấu trường, nhóm và khối) không bao giờ chạm vào một phần bộ nhớ cho đến khi nó thực sự cần thiết,” theo các nhận xét trong mã nguồn. Điều đó có nghĩa là một hồ bơi có thể có các khối ở 3 trạng thái. Các trạng thái này có thể được định nghĩa như sau:
Con Khi trình quản lý bộ nhớ làm cho các khối "trống", các Đấu trườngCác khu vực chứa hồ
bơi. Những hồ bơi có thể Thay vào đó, các khu vực được tổ chức thành một danh sách liên kết kép được gọi là Điều này có nghĩa là đấu trường có đầy đủ dữ liệu nhất sẽ được chọn để đặt dữ liệu mới vào. Nhưng tại sao không phải là ngược lại? Tại sao không đặt dữ liệu ở nơi có nhiều dung lượng nhất? Điều này đưa chúng ta đến ý tưởng giải phóng bộ nhớ thực sự. Bạn sẽ nhận thấy rằng tôi đã nói "miễn phí" trong dấu ngoặc kép khá nhiều. Lý do là khi một khối được coi là "trống", bộ nhớ đó không thực sự được giải phóng trở lại hệ điều hành. Quy trình Python giữ nó được phân bổ và sẽ sử dụng nó sau này cho dữ liệu mới. Thực sự giải phóng bộ nhớ sẽ trả nó trở lại hệ điều hành để sử dụng. Đấu trường là những thứ duy nhất có thể thực sự được giải phóng. Vì vậy, đó là lý do mà những đấu trường gần hơn trống rỗng nên được phép trở nên trống rỗng. Bằng cách đó, phần bộ nhớ đó có thể được giải phóng thực sự, giảm dung lượng bộ nhớ tổng thể của chương trình Python của bạn. Phần kết luậnQuản lý bộ nhớ là một phần không thể thiếu khi làm việc với máy tính. Python xử lý gần như tất cả mọi thứ đằng sau hậu trường, tốt hơn hoặc xấu hơn. Trong bài viết này, bạn đã học được:
Python loại bỏ rất nhiều chi tiết phức tạp khi làm việc với máy tính. Điều này mang lại cho bạn sức mạnh để làm việc ở cấp độ cao hơn để phát triển mã của bạn mà không phải đau đầu lo lắng về cách thức và nơi lưu trữ tất cả các byte đó. |