Ngôn ngữ
máy bao gồm những chỉ
thị (instruction) rất đơn giản mà
CPU máy tính có thể thực hiện trực tiếp. Tuy nhiên, hầu hết các
chương trình đều được viết bằng các ngôn ngữ lập trình bậc cao
như Java hay C++. Một chương trình viết bằng ngôn ngữ bậc cao cần
được dịch sang ngôn ngữ máy trước khi có thể được chạy trên máy
tính. Việc dịch này do trình biên dịch thực hiện. Để chạy trên các
loại máy tính với các ngôn ngữ máy khác nhau, cần đến các trình
biên dịch phù hợp với loại ngôn ngữ máy đó.
Có một lựa
chọn khác thay vì biên dịch chương trình viết bằng ngôn ngữ bậc
cao. Thay vì dùng một trình biên dịch để dịch thẳng toàn bộ chương
trình, ta có thể dùng một trình thông dịch, nó dịch từng chỉ thị một
và chỉ dịch khi cần đến. Một trình thông dịch là một chương trình
hoạt động gần như một CPU với một dạng chu trình nạp-và-thực-thi (fetch-and-execute). Để thực thi một
chương trình, trình thông dịch lặp đi lặp lại chuỗi công việc: đọc
một chỉ thị từ trong chương trình, xác định xem cần làm gì để
thực hiện chỉ thị đó, và rồi thực hiện các lệnh mã máy thích hợp
để thực hiện chỉ thị đó.
Một công
dụng của trình thông dịch là để thực thi các chương trình viết
bằng ngôn ngữ bậc cao, chẳng hạn như ngôn ngữ Lisp. Công dụng thứ
hai là chúng cho phép ta chạy một chương trình ngôn ngữ máy dành
cho một loại máy tính này trên một loại máy tính hoàn toàn khác.
Ví dụ, có một chương trình tên là "Virtual PC" chạy trên
các máy tính cài hệ điều hành Mac OS, đó là một trình thông dịch
thực thi các chương trình mã máy viết cho các máy tính tương
thích IBM PC. Nếu ta chạy "Virtual PC" trên một máy Mac OS, ta
có thể chạy bất cứ chương trình PC nào, trong đó có cả các
chương trình viết cho Windows.
Những người
thiết kế Java chọn cách tổ hợp giữa trình biên dịch và trình thông
dịch. Các chương trình viết bằng Java được biên dịch thành mã
máy, nhưng đây là loại ngôn ngữ máy dành cho loại máy tính không
tồn tại – loại máy "ảo" này được gọi là Máy ảo Java (Java Virtual Machine – JVM). Ngôn ngữ máy
dành cho máy ảo Java được gọi là Java bytecode, hay ngắn gọn là
bytecode. Để chạy được các chương trình Java trên một loại máy
tính bất kì, người ta chỉ cần một trình thông dịch dành cho Java
bytecode, trình thông dịch này giả lập máy ảo Java theo kiểu mà
Virtual PC giả lập một máy tính PC. Máy ảo Java cũng chính là tên
gọi dành cho trình thông
dịch bytecode
thực hiện nhiệm vụ giả lập, do đó ta nói rằng một máy tính cần một
máy ảo Java để chạy các chương trình Java.
Tất nhiên,
mỗi loại máy tính cần một trình thông dịch Java bytecode khác, nhưng
một khi đã có một trình thông dịch như vậy, nó có thể chạy một
chương trình Java bytecode bất kì. Và cũng chính chương trình Java
bytecode đó có thể chạy trên bất cứ máy tính nào có một trình
thông dịch Java bytecode. Đây chính là một trong các đặc điểm quan
trọng của Java: một chương trình sau khi biên dịch có thể chạy trên
nhiều loại máy tính khác nhau.
Có nhiều lý
do tại sao nên dùng mã trung gian là Java bytecode thay cho việc phân
phát mã nguồn chương trình Java và để cho mỗi người tự biên dịch
nó sang mã máy của máy tính họ đang dùng. Thứ nhất, trình biên
dịch là một chương trình phức tạp trong khi trình thông dịch chỉ
là một chương trình nhỏ và đơn giản. Viết một trình thông dịch
cho một loại máy tính mới dễ hơn là viết một trình biên dịch. Thứ
hai, nhiều chương trình Java cần được tải xuống từ mạng máy tính.
Việc này dẫn đến các mối quan tâm dễ thấy về bảo mật: ta không
muốn tải về và chạy một chương trình sẽ phá hoại máy tính hoặc
các file trong máy tính của ta. Trình thông dịch bytecode hoạt động
với vai trò bộ đệm giữa máy tính của ta và chương trình ta tải
về. Nó có thể bảo vệ ta khỏi các hành động nguy hiểm tiềm tàng
của chương trình đó.
Khi Java còn
là một ngôn ngữ mới, nó đã bị chỉ trích là chạy chậm. Do Java
bytecode được thực thi bởi một trình thông dịch, có vẻ như các
chương trình bytecode không bao giờ có thể chạy nhanh bằng các
chương trình đã được biên dịch ra ngôn ngữ máy của chính máy
tính mà chương trình đang chạy trên đó. Tuy nhiên, vấn đề này đã
được giải quyết gần như toàn bộ bằng việc sử dụng trình biên
dịch JIT (just-in-time
compiler)
cho việc thực thi Java bytecode. Trình biên dịch JIT dịch Java bytecode
thành mã máy. Nó làm việc này trong khi thực thi chương trình. Cũng
như một trình thông dịch thông thường, đầu vào cho một trình biên
dịch JIT là một chương trình Java bytecode, và nhiệm vụ của nó là
thực thi chương trình đó. Nhưng trong khi thực thi chương trình, nó
dịch một phần của chương trình ra mã máy. Những phần được biên
dịch này khi đó có thể được thực thi nhanh hơn là so
với khi
chúng được thông dịch. Do một phần của chương trình thường được
thực thi nhiều lần trong khi chương trình chạy, một trình biên dịch
JIT có thể cải thiện đáng kể tổng thời gian chạy của chương trình.
Đăng nhận xét