Ngôn ngữ được quản lý so với sự khác biệt về ngôn ngữ biên dịch?


18

Tôi bối rối khi mọi người cố gắng phân biệt giữa ngôn ngữ được biên dịch và ngôn ngữ được quản lý. Từ kinh nghiệm, tôi hiểu rằng hầu hết các ngôn ngữ được biên dịch là C, C ++ trong khi các ngôn ngữ được quản lý là Java, C # (Rõ ràng có nhiều hơn, nhưng đây chỉ là một vài ví dụ). Nhưng chính xác thì sự khác biệt cốt lõi giữa hai loại ngôn ngữ là gì?

Tôi hiểu rằng bất kỳ chương trình nào, bất kể ngôn ngữ nào bạn sử dụng về cơ bản đều được "biên dịch" thành mã máy cấp thấp, sau đó được giải thích, do đó, loại ngôn ngữ đó được quản lý thành một tập hợp con của các ngôn ngữ được biên dịch (Đó là tất cả các ngôn ngữ được quản lý biên dịch ngôn ngữ nhưng không phải là cách khác xung quanh)?


2
thuật ngữ này được đặt ra bởi Microsoft, theo nghĩa hẹp, Java cũng được quản lý. Hầu như trong mọi trường hợp chúng ta có thể nghĩ về ngôn ngữ được quản lý như một tập hợp con của một rằng compiles.Also, này, tôi tin rằng có liên quan - programmers.stackexchange.com/questions/72446/...
shabunc

Lưu ý rằng có một sự khác biệt rất lớn giữa một ngôn ngữ biên dịch (tĩnh) mã thành thứ gì đó dễ quản lý hơn máy trước khi chạy (như Java) và ngôn ngữ thực hiện trong thời gian chạy (như Python). Một điểm khác biệt lớn là việc biên dịch tĩnh nó trước khi chạy cho phép trình tạo cơ hội thực hiện một số tối ưu hóa có thể dẫn đến cải thiện tốc độ lớn (như JIT của Java, sắp xếp lại mã để dự đoán nhánh, v.v.).
Shivan Dragon

6
@ShivanDragon, một "ngôn ngữ" không biên dịch bất cứ thứ gì. Nó thực hiện không. Và bạn có thể biên dịch Python tĩnh (xem PyPy hoặc IronPython chẳng hạn). OTOH, thực sự rất khó để làm điều đó một cách hiệu quả với một ngôn ngữ được gõ động (tra cứu "truy tìm JIT", "giải thích trừu tượng", v.v.)
SK-logic

@ SK-logic: đã đồng ý, tôi đã nói một baddie. Tôi muốn đề cập đến nền tảng, không phải ngôn ngữ.
Shivan Dragon

@shabunc Thật ra tôi muốn nói Compiled là một tập hợp con của Managed. Ngôn ngữ được quản lý có thể làm bất cứ điều gì mà ngôn ngữ được biên dịch có thể làm (với tốc độ gần như nhau), và sau đó nhiều hơn vì ngôn ngữ được quản lý có thể được biên dịch. Để cung cấp cho C các tính năng của ngôn ngữ được quản lý, bạn cần xây dựng một "VM" và thực sự biến nó thành ngôn ngữ được quản lý.
Bill K

Câu trả lời:


47

Sự khác biệt không nằm ở "biên dịch" so với "được quản lý", đây là hai trục trực giao. Bằng cách "được quản lý", thông thường chúng có nghĩa là sự hiện diện của quản lý bộ nhớ được thu gom rác và / hoặc sự hiện diện của cơ sở hạ tầng máy ảo. Cả hai hoàn toàn không có gì để làm với việc biên dịch và bất cứ điều gì mọi người cho là đối nghịch với nó.

Tất cả "sự khác biệt" này khá mờ nhạt, giả tạo và không liên quan, vì luôn có thể trộn bộ nhớ được quản lý và không được quản lý trong một thời gian chạy, và sự khác biệt giữa biên dịch và giải thích cũng rất mơ hồ.


2
Đây là những gì tôi về cơ bản đã có trong đầu, nhưng tôi đã bắt gặp rất nhiều người tiếp tục tạo ra sự khác biệt này. Cảm ơn câu trả lời rõ ràng.
l46kok

Mã được quản lý có nghĩa là có một ngôn ngữ trung gian để được chăm sóc bất cứ môi trường thực thi nào bạn đang chạy trong thời gian chạy, phải không? Vì vậy, ngôn ngữ trung gian (giả sử mã byte) phải được tạo bởi trình biên dịch. IMO, cặp vợ chồng "quản lý" mã và khái niệm "biên dịch" một chút. Tuy nhiên, nếu ngôn ngữ được "biên dịch", điều đó không cho thấy nó mang lại mã được quản lý (ví dụ: C ++ so với Java)
zgulser

@zgulser, không, ngôn ngữ trung gian là trực giao. Được quản lý có nghĩa là có một GC tích hợp với thời gian chạy ngôn ngữ. Ví dụ, thời gian chạy OCaml được "quản lý", mặc dù nó biên dịch thẳng sang nguồn gốc.
SK-logic

8

Để trích dẫn Wikipedia:

Mã được quản lý là thuật ngữ do Microsoft đặt ra để xác định mã nguồn chương trình máy tính yêu cầu và sẽ chỉ thực thi dưới sự quản lý của máy ảo Runtime Ngôn ngữ chung (kết quả là mã byte).

Mã được quản lý cần một thời gian chạy (như .NET CLT) để thực thi.


5
Mã được quản lý không có gì để làm với một khung. Nó cần một thời gian chạy quản lý bộ nhớ.
Oded

Có lẽ cách diễn đạt của tôi hơi sai, nhưng .NET framework thực sự không phải là "thời gian chạy ngôn ngữ chung"?
janvdl

3
Không. Bao gồm CLR, nhưng nó cũng bao gồm các Thư viện lớp cơ sở, đặc tả IL và hơn thế nữa.
Oded

4

Tôi nghĩ rằng có một sự khác biệt cần được thực hiện, tuy nhiên nó không nhất thiết phải là "Biên dịch" và "Được quản lý". Đây không phải là đối lập; một ngôn ngữ có thể được biên dịch và không được quản lý, hoặc giải thích (không được biên dịch) và được quản lý, hoặc cả hai, hoặc thậm chí là không.

Một ngôn ngữ "được biên dịch" chỉ đơn giản là một ngôn ngữ trong đó có một bước chuyển đổi mã nguồn được nhà phát triển viết thành một "mã byte" thông thường hơn, đó là thứ được thực thi bởi máy. "Máy" có thể là bộ xử lý thực tế hoặc "máy ảo" thực hiện các hoạt động bổ sung trên mã byte để dịch chúng sang hướng dẫn máy "gốc". Từ trái nghĩa của ngôn ngữ "đã biên dịch" là ngôn ngữ "được diễn giải", trong đó mã nguồn được chuyển đổi thành các lệnh bytecode trong thời gian chạy, từng dòng khi chúng được thực thi, không có bước biên dịch. Một kết hợp giữa chúng là "jits", từ "JIT" (Just In Time), thường được hiểu là một bước một lần của máy thực thi;

Ngôn ngữ "được quản lý" là ngôn ngữ được thiết kế để tạo ra các chương trình được sử dụng trong môi trường thời gian chạy cụ thể, hầu như luôn bao gồm trình thông dịch mã byte; một "máy ảo" lấy mã của chương trình và thực hiện một số chuyển đổi bổ sung cho từng máy hoặc môi trường cụ thể. Môi trường cũng có thể bao gồm quản lý bộ nhớ, chẳng hạn như "trình thu gom rác" và các tính năng "bảo mật" khác để giữ cho chương trình hoạt động trong "hộp cát" không gian và công cụ của nó, tuy nhiên các tính năng này không phải là miền duy nhất của thời gian chạy "được quản lý" . Hầu như tất cả các ngôn ngữ được thông dịch đều có thể được coi là được quản lý, bởi vì chúng yêu cầu trình thông dịch phải chạy bên dưới các dòng mã "người dùng" đang được thực thi. Ngoài ra, các ngôn ngữ JVM và .NET (Java, Scala, C #, VB, F #, IronWhthing) được biên dịch thành ngôn ngữ trung gian hoặc IL, tương tự bề ngoài về hình thức và chức năng với ngôn ngữ lắp ráp nhị phân, nhưng không tuân thủ 100% với bất kỳ tập lệnh "gốc" nào. Các hướng dẫn này được thực thi bởi JVM hoặc bởi CLR của .NET, giúp chuyển đổi chúng thành các hướng dẫn nhị phân riêng cụ thể cho kiến ​​trúc CPU và / hoặc HĐH của máy.

Vì vậy, các ngôn ngữ thường có thể được mô tả là "biên dịch" hoặc "diễn giải" và "không được quản lý" (hoặc "bản địa") và "được quản lý". Có những ngôn ngữ có thể được mô tả như bất kỳ sự kết hợp nào của những ngôn ngữ này ngoại trừ "bản dịch được giải thích" có thể (điều này chỉ đúng với các mã thập lục phân viết tay, trong đó những gì được viết bởi nhà phát triển là những gì được thực thi); nếu bạn coi lớp diễn giải là "thời gian chạy" (dễ tranh luận và khó tranh luận), thì tất cả các ngôn ngữ được diễn giải đều được "quản lý".

Nếu bạn muốn có được kỹ thuật, hầu như tất cả các chương trình nhắm mục tiêu một hệ điều hành đa nhiệm hiện nay đều được "quản lý"; HĐH sẽ tạo ra một "máy ảo" cho mỗi chương trình đang chạy, trong đó chương trình nghĩ (hoặc ít nhất là không phải biết khác) rằng đó là thứ duy nhất đang chạy. Mã có thể thực hiện các cuộc gọi trong chính nó và tới các thư viện được tham chiếu khác như thể chương trình đó là thứ duy nhất được tải trong bộ nhớ; tương tự, các lệnh gọi để phân bổ RAM và bộ nhớ cao hơn khác để lưu trữ và thao tác dữ liệu và thiết bị điều khiển được mã hóa như thể toàn bộ kiến ​​trúc bộ nhớ có sẵn. Sau đó, VM (và HĐH đằng sau nó) dịch các con trỏ bộ nhớ khác nhau sang vị trí thực tế của chương trình, dữ liệu của nó và móc vào trình điều khiển thiết bị, v.v. Điều này thường được thực hiện bằng cách áp dụng bù bộ nhớ (mỗi VM có một khối 2GB hoặc bất cứ điều gì của bộ nhớ, bắt đầu từ địa chỉ X mà chương trình có thể xử lý như thể X là địa chỉ 0) và như vậy rất rẻ để làm, nhưng có những thứ khác mà nhân hệ điều hành chịu trách nhiệm, chẳng hạn như lập lịch xử lý và giao tiếp giữa các quá trình, đó là phức tạp hơn để quản lý. Tuy nhiên, mẫu cơ bản này thường không được coi là "được quản lý", vì chương trình không phải biết rằng nó đang được điều hành bởi một máy ảo và thường vẫn có trách nhiệm giữ cho bộ nhớ được phân bổ của nó "sạch". Một chương trình được thiết kế để chạy trên dòng lệnh MS-DOS có thể chạy trên các HĐH Windows mới hơn, thậm chí không có môi trường MS-DOS bên dưới chúng nữa; thay vào đó, chương trình được cung cấp một môi trường "bảng điều khiển ảo" và với điều kiện là nó không cố rời khỏi "hộp cát" này


"Các ngôn ngữ thường có thể được mô tả là" được biên dịch "hoặc" diễn giải "" - Không, chúng không thể. Biên dịch và giải thích là những đặc điểm của, tốt, trình biên dịch và phiên dịch không phải ngôn ngữ. Thuật ngữ "ngôn ngữ biên dịch" thậm chí không có ý nghĩa. Nếu tiếng Anh là ngôn ngữ đánh máy, đó sẽ là một lỗi loại.
Jörg W Mittag

2
Trình biên dịch và thông dịch viên thường được tìm thấy biên dịch và giải thích các phương ngữ rất cụ thể của các ngôn ngữ được thiết kế để trải qua quá trình biên dịch hoặc phiên dịch. Không ai biên dịch mã nguồn JavaScript mà tôi biết và không ai giải thích C #. Các ngôn ngữ được thiết kế để được tiêu thụ theo cách này hay cách khác. Do đó, thường được chấp nhận để gọi chính ngôn ngữ là "được biên dịch" hoặc "diễn giải" bởi vì môi trường đầy đủ mà ngôn ngữ được sử dụng bao gồm một trong hai bước đó.
KeithS


vi.wikipedia.org/wiki/Interprave_lingu - "Về mặt lý thuyết, bất kỳ ngôn ngữ nào cũng có thể được biên dịch hoặc giải thích, do đó, chỉ định này được áp dụng hoàn toàn vì thực tiễn triển khai chung và không phải là một thuộc tính thiết yếu của ngôn ngữ."
KeithS

@KeithS, wikipedia gần như không hoàn hảo. Việc một bài viết tồn tại cho một thuật ngữ không hợp lệ nhất định không làm cho thuật ngữ này trở nên hợp lệ hơn. Đúng, các ngôn ngữ luôn được thiết kế với một chế độ thực thi nhất định, nhưng nó vẫn phản tác dụng đối với thương hiệu chúng "được biên dịch" hoặc "diễn giải" chỉ dựa trên ý định thiết kế của chúng. Và, như đối với một giải thích, thực sự rất khó để tìm một "thông dịch viên" thích hợp bằng mọi cách. Tcl có lẽ là cuối cùng của loại hình này. Tất cả những cái khác được gọi là "thông dịch viên" trong thực tế là trình biên dịch.
SK-logic

2

Ngôn ngữ được quản lý theo thuật ngữ đơn giản, đây là ngôn ngữ cấp cao phụ thuộc vào các dịch vụ được cung cấp bởi môi trường thời gian chạy để thực thi, chẳng hạn như dịch vụ thu gom rác, đó là lý do tại sao nó được gọi là quản lý chung nhưng đó không phải là dịch vụ duy nhất mà nó sử dụng và một số dịch vụ này security services, exception handling, standard types, nó sử dụng Common Language Run-time CLRđể thực thi, như trong các ngôn ngữ .Net hoặc một môi trường ảo như Java sử dụng `Java Virtual Machine JVM.

Ngôn ngữ không được quản lý là ngôn ngữ cấp thấp do hệ điều hành thực thi trực tiếp mà không cần dịch vụ thời gian ảo hoặc ngôn ngữ trung gian, các ngôn ngữ như C, C++mã không được quản lý được tạo bởi các ngôn ngữ đó sử dụng các thường trình thư viện được liên kết động với HĐH để có được mã để thực thi được gọi là DLL (Thư viện liên kết động), mã không được quản lý truy cập trực tiếp vào bộ nhớ, đó là lý do tại sao nó nhanh hơn mã được quản lý, nhưng trừ khi bạn đang xây dựng trình điều khiển phần cứng hoặc trò chơi video tinh vi, bạn không thực sự muốn sử dụng các ngôn ngữ không được quản lý như Nó có thể trở nên nguy hiểm khi làm việc với đặc biệt là với các nhà phát triển thiếu kinh nghiệm như trạng thái vai tròwith great power comes great responsibilityvà đó là lý do tại sao các ngôn ngữ được quản lý tồn tại để giúp các nhà phát triển tạo mã mở rộng mà không cần đi sâu vào cuối hệ thống, nhưng bạn vẫn có thể tạo mã hỗn hợp nếu bạn cần, những bài viết này giải thích tất cả:

Tổng quan về khả năng tương tác mã được quản lý / không được quản lý

Ví dụ: Trộn mã C ++, C ++ / CLI và C # không được quản lý

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.