1- JDK

Viết tắt của Java Development Kit (JDK), bao gồm cả JRE và JVM, đây là phần lõi của môi trường java, nó cung cấp tất cả môi trường để thực thi, phát triển, gỡ lỗi và giám sát các ứng dụng java. Jdk phụ thuộc vào nền tảng hệ điều hành, nên sẽ có nhiều loại phiên bản jdk khác nhau.

JDK bao gồm:

  • Development Tool: cung cấp môi trường để phát triển các ứng dụng java
  • JRE: thực thi chương trình java

2- JRE

Viết tắt của Java Runtime Environment, là một gói cài đặt cung cấp môi trường để chỉ chạy (không phát triển) chương trình java (hoặc ứng dụng) trên máy của bạn. JRE chỉ được sử dụng bởi những người chỉ muốn chạy các chương trình Java, cũng chính là end-user hệ thống của bạn.

3- JVM

Viết tắt của Java Virtual Machine, được phát triển với khái niệm WORA (Write Once Run Anywhere), JVM là một phần rất quan trọng của JRE và JDK vì nó đều được chứa hoặc có sẵn trong cả hai và có nhiệm vụ dùng để thực thi chương trình java.

JVM thực hiện các công việc chính sau:

  • Thực hiện tải code, resource
  • Cung cấp môi trường runtime
  • Kiểm tra code: kiểm tra các lỗi cú pháp, lỗi chương trình,…
  • Thực thi code
Hình 1

4- Kiến trúc JVM

Hình 2: Kiến trúc JVM

JVM chia thành ba hệ thống con chính: Class Loader (trình khởi tạo lớp con), Runtime, Execution Engine (công cụ thực thi)

Class Loader: Chức năng tải lớp động của Java được xử lý bởi hệ thống con Class Loader. Chịu trách nhiệm tải, liên kết và khởi tạo tệp lớp khi nó tham chiếu đến một lớp lần đầu tiên trong thời gian chạy, không phải thời gian biên dịch.

4.1 Loading : Các lớp sẽ được tải bởi thành phần này. Bootstrap ClassLoader, Extension ClassLoader và Application ClassLoader là ba ClassLoader sẽ giúp đạt được điều đó.

  • Bootstrap ClassLoader: nhiệm vụ dùng để tải các lớp ở đường dẫn bootstrap
  • Extension ClassLoader: nhiệm vụ dùng để tải các lớp nằm trong đường dẫn jre\lib\ext
  • Application ClassLoader: nhiệm vụ dùng để tải tệp và lớp cấp ứng dụng, đường dẫn path được đề cập trong biến môi trường hệ thống
  • Nếu lớp được tìm thấy bởi một trình tải lớp nào mà được tải bởi một trình tải lớp khác thì exception ClassNotFoundException sẽ được bắn ra.

4.2 Linking : Sau khi lớp được tải bởi trình nạp lớp (Loading), Linking(liên kết) được thực hiện. Trình xác minh bytecode sẽ xác minh xem bytecode được tạo có phù hợp hay không. Nếu xác minh không thành công sẽ gặp lỗi xác minh. Đồng thời nó cũng thực hiện việc cấp phát bộ nhớ cho các biến và phương thức tĩnh được tìm thấy trong lớp.

Runtime Data Area: vùng bộ nhớ bên trong JVM được chia thành nhiều phân vùng khác nhau để thực hiện lưu trữ các phần ứng dụng cụ thể, được chia thành 5 phần chính:

  • Method Area: tất cả dữ liệu mức lớp như constant pool, field, method, data… sẽ được lưu trữ ở đây, chỉ có 1 method area trên mỗi JVM nên nó là tài nguyên được chia sẻ.
  • Heap Area (bộ nhớ Heap): lưu trữ tất cả các đối tượng được tạo ra trong quá trình thực thi ứng dụng.
  • Stack Area (bộ nhớ Stack): đối với từng luồng, bộ nhớ stack dành riêng cho từng luồng sẽ được tạo ra, tất cả các biến cục bộ theo từng luồng sẽ được tạo ra trong bộ nhớ stack. Bộ nhớ stack không chia sẻ dữ liệu chung cho nhiều luồng nên dữ liệu được đảm bảo an toàn theo từng luồng.
  • PC Register (thanh ghi PC): có nhiệm vụ lưu trữ địa chỉ bộ nhớ vật lý của các câu lệnh được thực thi tại thời điểm hiện tại. Trong Java, mỗi luồng có một thanh ghi PC riêng biệt.
  • Native Method Stack: chứa thông tin về phương thức gốc, chúng ta có thể viết phương thức gốc của ngôn ngữ như C, C++ khi sử dụng từ khóa native.

Execution Engine (Công cụ thực thi): Tất cả mã được gán cho JVM được thực thi bởi một công cụ thực thi. Công cụ thực thi đọc mã byte và thực thi từng cái một. Nó sử dụng trình thông dịch sẵn có và trình biên dịch JIT để chuyển đổi mã bytecode thành mã máy và thực thi nó. Cả trình thông dịch và trình biên dịch đều tạo ra mã gốc, tuy nhiên sự khác biệt là ở cách nó tạo ra mã gốc, mức độ tối ưu hóa cũng như chi phí tối ưu hóa của hai loại là khác nhau.

  • Interpreter (trình thông dịch): trình thông dịch diễn giải ra ra mã bytecode nhanh hơn nhưng thực thi chậm hơn do nó không thực hiện bất kì tối ưu hóa nào. Nhược điểm của trình thông dịch là khi một phương thức được gọi nhiều lần, thì tương ứng mỗi lần thông dịch được gọi.
  • JIT Compiler (trình biên dịch): trình biên dịch JIT có nhiệm vụ vô hiệu hóa nhược điểm của trình thông dịch. Công cụ thực thi sẽ sử dụng sự trợ giúp của trình thông dịch trong việc chuyển đổi mã byte, nhưng khi nó tìm thấy mã lặp lại, nó sử dụng trình biên dịch JIT để hỗ trợ tối ưu hóa. Trình biên dịch JIT sẽ biên dịch khối mã bytecode và thay đổi nó thành mã gốc. Mã gốc này sẽ được sử dụng trực tiếp cho các cuộc gọi phương thức lặp lại, giúp cải thiện hiệu năng của hệ thống.
  • Garbage Collection: thực hiện thu thập các đối tượng không được tham chiếu và loại bỏ nó.

5- Sự khác biệt giữa JDK, JRE, JVM

Hình 3: Cấu trúc phân tầng JDK – JRE – JVM
JRE = JVM + Các thư viện dùng để chạy ứng dụng JAVA
JDK = JRE + Các thư viện dùng để phát triển ứng dụng JAVA

Nếu nhu cầu chỉ cần chạy chương trình java thì chỉ cần JRE, nếu nhu cầu phát triển chương trình java thì cần phải cài JDK. Vậy là chúng ta đã kết thúc việc phân biệt JDK JRE và JVM trong java

Xem thêm các bài viết liên quan dưới đây: