2009-08-25 40 views
103

Trong quá khứ tôi đã sử dụng C++ làm ngôn ngữ lập trình. Tôi biết rằng mã được viết bằng C++ đi qua một quá trình biên dịch cho đến khi nó trở thành mã đối tượng "mã máy".Java có phải là một ngôn ngữ lập trình được biên dịch hay được diễn giải không?

Tôi muốn biết Java hoạt động như thế nào trong khía cạnh đó. Mã Java được người dùng viết bởi máy tính như thế nào?

+12

C++ có thể được diễn giải. Có một vài thông dịch viên C ngoài kia. –

Trả lời

38

Java được biên dịch sang bytecode, sau đó được đưa vào máy ảo Java, giải thích nó.

+0

câu trả lời đơn giản và tốt đẹp –

+24

... nhưng không hoàn toàn chính xác. –

+1

JVM có thể chọn không "giải thích" bytecode. Nó có thể JIT biên dịch nó và thực thi nó trực tiếp. –

10

Java là một ngôn ngữ lập trình được biên dịch, nhưng thay vì biên dịch thẳng sang mã máy thực thi, nó biên dịch thành một dạng nhị phân trung gian được gọi là mã byte JVM. Mã byte sau đó được biên dịch và/hoặc giải thích để chạy chương trình.

0

Java là ngôn ngữ được biên dịch theo byte nhắm mục tiêu nền tảng có tên là Java Virtual Machine dựa trên nền tảng xếp chồng và có một số triển khai rất nhanh trên nhiều nền tảng.

+0

"Biên dịch byte" nghĩa là gì? – Jesper

+2

@Jesper: "Biên dịch Byte" thường có nghĩa là "được biên dịch sang bytecode". "Bytecode" là một thuật ngữ chung bao gồm bất kỳ loại mã trung gian phi văn bản nào (thường không phải là máy thực thi). –

12

Loại cả hai. Thứ nhất là biên dịch java (một số muốn nói "dịch") sang bytecode, sau đó được biên dịch, hoặc diễn dịch tùy thuộc vào tâm trạng của JIT.

+22

Đó là một phần nâng cao của phần mềm, để phát triển tâm trạng :) – Thorarin

+4

JIT thực sự là một phần rất tinh vi của phần mềm, có thể làm tối ưu hóa dựa trên thông tin thời gian chạy (như một hồ sơ), mà một trình biên dịch trước thời gian có thể ' t (vì nó không có thông tin về hành vi thời gian chạy của một chương trình trước thời hạn). Nhưng nó có thể không thực sự có tâm trạng ... :-) – Jesper

141

Triển khai Java thường sử dụng quy trình biên dịch hai bước. Mã nguồn Java được biên dịch xuống bytecode bởi trình biên dịch Java. Bytecode được thực thi bởi một máy ảo Java (JVM). Các JVM hiện đại sử dụng kỹ thuật gọi là Just-in-Time (JIT) compilation để biên dịch bytecode thành các chỉ lệnh gốc được hiểu bởi CPU phần cứng khi đang chạy.

Một số triển khai của JVM có thể chọn để giải thích bytecode thay vì JIT biên dịch nó thành mã máy và chạy trực tiếp. Trong khi điều này vẫn được coi là một "thông dịch viên", nó hoàn toàn khác với các thông dịch viên đọc và thực thi mã nguồn cấp cao (tức là trong trường hợp này, mã nguồn Java không được giải thích trực tiếp, bytecode, đầu ra của trình biên dịch Java,.)

Về mặt kỹ thuật, có thể biên dịch Java xuống mã gốc trước và chạy kết quả nhị phân. Cũng có thể diễn giải mã Java trực tiếp.

Để tóm tắt, tùy thuộc vào môi trường thực thi, bytecode có thể là:

  • biên soạn trước thời hạn và thực hiện như mã gốc (tương tự như hầu hết các trình biên dịch C++)
  • biên soạn just-in-time và thực hiện
  • giải thích
  • trực tiếp thực hiện bởi một bộ xử lý được hỗ trợ (bytecode là tập hướng dẫn bản địa của một số CPU)
+12

Trên thực tế, một số JVM HotSpot bắt đầu bằng cách giải thích bytecode, và chỉ biên dịch chúng thành mã gốc sau khi chúng đã tìm ra giá trị biên dịch và thu thập một số thống kê về cách mã đang được chạy; ví dụ. để tìm ra con đường phổ biến nhất được thực hiện trong mỗi nhánh có điều kiện. –

+0

Do đó thuật ngữ 'Hotspot' :) Nó hoạt động với những gì đang chạy thường xuyên, để đạt được một tối ưu hóa. –

+4

Bạn có thể tắt thông dịch viên trong HotSpot bằng -Xcomp. Giá trị cố gắng trên một ứng dụng để xem đó là một ý tưởng tồi. –

43

Các thuật ngữ "ngôn ngữ diễn giải" hoặc "ngôn ngữ biên soạn" không có ý nghĩa, bởi vì bất kỳ ngôn ngữ lập trình nào cũng có thể được hiểu và/hoặc biên dịch.

Đối với các cài đặt hiện có của Java, hầu hết liên quan đến một bước biên dịch sang bytecode, vì vậy chúng liên quan đến việc biên dịch. Thời gian chạy cũng có thể tải bytecode động, do đó, một số dạng của một trình thông dịch bytecode luôn cần thiết. Thông dịch viên đó có thể hoặc không thể sử dụng trình biên dịch thành mã gốc trong nội bộ.

Những ngày này phần biên dịch chỉ trong thời gian được sử dụng cho nhiều ngôn ngữ đã từng được coi là "diễn giải", ví dụ như Javascript.

+0

Cảm ơn bạn đã trả lời * chỉ * sane và chính xác trên toàn bộ trang. Tôi đã nghiêm túc bắt đầu đặt câu hỏi về trí thông minh của cộng đồng SO. Chỉ cần một số bổ sung nhanh: không phải tất cả các bản cài đặt Java đều biên dịch sang mã bytecode JVM. GNU GCJ có thể biên dịch thẳng thành mã gốc. Ngoài ra, không phải tất cả các JVM đều giải thích bytecode. Máy ảo Maxine Research của Sun không chứa một trình thông dịch, thay vào đó nó chứa hai trình biên dịch: một trình biên dịch rất nhanh tạo ra mã chậm được sử dụng khi các JVM khác sử dụng trình thông dịch của họ, và một trình chậm tạo mã nhanh được sử dụng để tối ưu hóa điểm phát sóng . –

+2

Ngoài ra, Công cụ thực thi JavaScript V8 của Google không chỉ thực hiện biên dịch một phần trong thời gian. Nó * luôn * biên dịch thành mã gốc, trên thực tế, V8 thậm chí không * có * một thông dịch viên. Nó có * chỉ * trình biên dịch (tương tự như Maxine, nhưng không giống như Maxine V8 chỉ có một trình biên dịch). Tất cả ba ví dụ này (GCJ, Maxine và V8) chứng tỏ quan điểm của bạn mạnh mẽ hơn: không có ngôn ngữ nào như ngôn ngữ thông dịch hay ngôn ngữ được biên dịch. Một ngôn ngữ không được diễn giải hoặc biên dịch. Một ngôn ngữ chỉ * là * (Đó là trích dẫn của Shriram Krishnamurthi). –

+2

Tại sao bạn lại nói về javascript trong một câu hỏi java? –

-1

Báo giá từ: https://blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

nhà phát triển ứng dụng có thể phát triển các ứng dụng mã trên bất kỳ hệ điều hành khác nhau mà có sẵn trong thị trường hiện nay. Ngôn ngữ Java là bất khả tri ở giai đoạn này với hệ điều hành. Mã nguồn tuyệt vời được viết bởi nhà phát triển ứng dụng Java hiện được biên dịch sang mã Java Byte trong thuật ngữ Java được gọi là biên dịch phía máy khách. Việc biên dịch này sang mã Java Byte là điều cho phép các nhà phát triển Java 'viết một lần'. Mã Java Byte có thể chạy trên bất kỳ hệ điều hành và máy chủ tương thích nào, do đó làm cho mã nguồn bất khả xâm phạm của OS/Server. Đăng tạo mã Byte Java, tương tác giữa ứng dụng Java và hệ điều hành/máy chủ cơ bản là thân mật hơn. Hành trình tiếp tục - Khung ứng dụng doanh nghiệp thực hiện các mã Java Byte này trong một môi trường thời gian chạy được gọi là Java Virtual Machine (JVM) hoặc Java Runtime Environment (JRE). JVM có quan hệ gần gũi với hệ điều hành và phần cứng cơ bản vì nó tận dụng các tài nguyên được cung cấp bởi hệ điều hành và máy chủ. Mã Java Byte bây giờ được biên dịch thành một mã thực thi ngôn ngữ máy là nền tảng cụ thể. Điều này được gọi là biên dịch phía máy chủ.

Vì vậy, tôi sẽ nói Java chắc chắn là một ngôn ngữ được biên dịch.

31

[1] Hình ảnh dưới đây giải thích rằng tất cả ...

enter image description here

Mã được viết bằng Java là:

  • Đầu tiên biên soạn để bytecode bởi một chương trình gọi là javac như được hiển thị trong phần bên trái của hình ảnh ab ove;
  • Sau đó, như thể hiện trong phần bên phải của hình ảnh trên, [2] một chương trình gọi là java bắt đầu môi trường thời gian chạy Java và nó có thể biên dịch và/hoặc giải thích bytecode bằng Java Biên dịch viên/Bộ biên dịch JIT.

Khi nào java giải thích các bytecode và khi nào nó biên dịch nó?[3] Mã ứng dụng ban đầu được giải thích, nhưng JVM giám sát chuỗi các bytecode thường xuyên được thực thi và dịch chúng sang mã máy để thực thi trực tiếp trên phần cứng. Đối với mã byte được thực hiện chỉ một vài lần, điều này sẽ tiết kiệm thời gian biên dịch và giảm độ trễ ban đầu; cho bytecode được thực hiện thường xuyên, biên dịch JIT được sử dụng để chạy ở tốc độ cao, sau một giai đoạn đầu diễn giải chậm. Ngoài ra, kể từ khi một chương trình dành phần lớn thời gian thực hiện một phần nhỏ của mã của nó, thời gian biên dịch giảm là đáng kể. Cuối cùng, trong quá trình giải mã mã ban đầu, các thống kê thực thi có thể được thu thập trước khi biên dịch, giúp tối ưu hóa tốt hơn.


Nhấp vào số siêu trong câu trả lời để tham khảo.

+0

Có phải do bytecode được lưu trong bộ nhớ cache mà Java sử dụng nhiều bộ nhớ không? –

+2

@sedulam: Rất nhiều bộ nhớ là một câu lệnh mờ. Quản lý bộ nhớ của Java khá đơn giản - Ba thế hệ là những gì JVM sử dụng để tạo và duy trì các đối tượng của nó. [Câu trả lời SO khác] (https://stackoverflow.com/q/3496442) có thể hữu ích cho bạn. – displayName

+0

Với giải thích trên, về mặt lý thuyết, mã được biên dịch C++ sẽ luôn nhanh hơn mã java tương tự về mặt logic vì sẽ luôn có một phần tệp .class mà JIT quyết định không chuyển thành mã máy. Nói cách khác, java không bao giờ có thể bắt được tốc độ thực thi kim loại trần mà C++ đã chứng minh. Đây có phải là giả định chính xác không? – DevdattaK

Các vấn đề liên quan