Java có JVM, C có gì?


15

Tôi biết rằng C có một trình biên dịch nhưng điều gì quyết định hiệu năng thực thi?

Ví dụ: trong một khối if khác, nếu mã chỉ có tất cả các if thay vì if elses, thì điều gì xác định rằng tất cả các if sẽ được chạy? Trong Java nó sẽ là JVM, nhưng trong C, trình biên dịch thực thi là gì?


16
Một sắc thái hữu ích để học là ngôn ngữ chỉ là ngôn ngữ. Bạn có thể tạo một trình biên dịch lấy mã C và làm cho nó chạy trong JVM chẳng hạn.
Telastyn

10
+1. Đây là một câu hỏi rất hay. Tôi sẽ không đánh giá thấp nó vì sự thiếu hiểu biết của nó - thật ngạc nhiên khi nhiều sinh viên Java không hỏi điều này.
djechlin

Bạn cũng có thể biên dịch Java thành mã máy và tránh JVM ...
AK_

2
Ngoài ra: Ngôn ngữ lập trình! = Framework! = Thư viện thời gian chạy! = Trình biên dịch! = Chỉ trong trình biên dịch thời gian! = Interperter
AK_

Câu trả lời:


17

Trong Java, máy ảo thực thi mã của bạn, nhưng trình biên dịch C tạo mã mà máy thật thực thi. Nói chính xác, trong cả hai trường hợp, chương trình của bạn cuối cùng được chuyển đổi thành mã máy thực sự, nhưng trong trường hợp Java, có một bước giữa để biên dịch sang mã byte JVM.

Vì vậy, các chương trình Java được JVM chuyển đổi thành các hướng dẫn thực khi bạn tải chúng, trong khi các chương trình C đã được trình biên dịch chuyển đổi thành các hướng dẫn thực trước khi chúng chạy.


20
Có các trình biên dịch lấy Java và tạo mã máy. Ví dụ máy bay phản lực Excelsior . Ngoài ra còn có các giao thoa cho C ( picoc ) không bao giờ tạo mã mà máy thật thực thi. Ngôn ngữ là ngôn ngữ. Triển khai là thực hiện. Nhầm lẫn hai có thể gây nhầm lẫn cho mọi người.

6

Ngoài mã máy, không có ngôn ngữ lập trình nào tồn tại trực tiếp trên phần cứng, theo nghĩa là bạn không thể cung cấp cho nó văn bản nguồn theo nghĩa đen. Tất cả các triển khai thực tế phải dịch chương trình nguồn sang ngôn ngữ của "máy".

Đối với một số triển khai, nó được dịch tĩnh. Chúng tôi thường gọi những triển khai này là "biên dịch". Đối với những người khác, nó được dịch sang một số hình thức trung gian, sau đó được dịch động khi chương trình được chạy. Chúng tôi thường gọi những triển khai này là "diễn giải". Có rất nhiều khả năng giữa những điều này và thậm chí nhiều CPU hiện đại thực hiện dịch động như một phần của lõi thực thi của nó.

Ngay cả khi chương trình của bạn được biên dịch tĩnh từ lâu trước khi thực thi, trừ khi bạn đang viết chương trình cơ sở, hiếm khi mã được biên dịch chạy trực tiếp trên kim loại trần mà không có gì hỗ trợ. Hệ điều hành cung cấp một máy ảo cho các chương trình không gian người dùng, thường cung cấp các tính năng như ảo ảnh rằng bạn có một CPU cho riêng mình. Ảo tưởng về một không gian bộ nhớ phẳng có thể lớn hơn RAM vật lý được gắn vào máy thậm chí còn được gọi là "bộ nhớ ảo".

Trên hết, ngay cả khi bạn đang lập trình trong C, vẫn có một máy ảo C! Theo truyền thống, nó được gọi là "thời gian chạy C" hoặc viết tắt là CRT.

Do C chủ yếu được dịch trực tiếp sang mã máy lắp ráp / trước thời hạn (trên một số nền tảng, cũng có thể có một số mã luồng và có thể được coi là một phần của máy ảo), nên máy ảo thường chỉ phải xử lý khởi động và tắt.

Khởi động thường bao gồm thiết lập ngăn xếp và đống; hệ điều hành hiếm khi cung cấp những thứ này cho bạn và đó là công việc của ngôn ngữ lập trình để cung cấp chúng cho lập trình viên. Trên một số nền tảng có thể có một số khởi tạo xử lý tín hiệu, thiết lập luồng "chính" trong môi trường đa luồng, chạy các hàm tạo toàn cầu trong trường hợp chương trình được liên kết với mã C ++, xử lý các thư viện được liên kết động hoặc ở đó có thể là một số xử lý cần thiết để thiết lập argc / argv và envp. Cuối cùng, CRT chuyển điều khiển sang chính.

Đối với tắt máy, nhiều hệ điều hành có thể giết chết một quá trình một cách không sạch sẽ, vì vậy tắt máy không cần phải làm gì nhiều. Điều chính là xử lý các lệnh gọi atexit () cho trường hợp chương trình thoát ra một cách sạch sẽ.


2
Thời gian chạy C và JVM, là những con thú hoàn toàn khác nhau. CRT chỉ là một thư viện.
DeadMG

Tôi đã chỉnh sửa câu trả lời để làm cho mọi thứ rõ ràng hơn một chút. Ngẫu nhiên, JVM và VirtualBox cũng là những quái thú hoàn toàn khác nhau.
Bút danh

@Pseudonymous: không thực sự. Chà, được thôi, VirtualBox là một trình ảo hóa, trong khi JVM điển hình là một trình giả lập, nhưng nếu bạn thay thế, ví dụ VirtualBox bằng QEmu trong câu của bạn, thì thực tế cả hai đều giống nhau.
Jörg W Mittag
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.