Trang chủ » JVM là gì? Cách hoạt động của Java Virtual Machine (JVM)
JVM là gì? Cách hoạt động của Java Virtual Machine (JVM)
- 23/02/2023
- LANIT JSC
Java Virtual Machine JVM là một trong những yếu tố quan trọng nhất của ngôn ngữ lập trình Java. Nó là phần mềm cài đặt trên các thiết bị cục bộ và có khả năng chạy trên nhiều HĐH. Việc hiểu rõ về khái niệm và kiến trúc hay lợi ích mà JVM là điều rất quan trọng.
1. Khái niệm JVM là gì?
Java Virtual Machine (JVM) là môi trường thực thi độc lập với nền tảng cho ngôn ngữ Java. JVM đóng vai trò như một “máy ảo” nhằm thực thi chương trình viết bằng bytecode. Có thể chạy trên nhiều hệ điều hành khác nhau như Windows, Linux và MacOS.
Chương trình Java được biên dịch thành mã byte code và mã này sẽ được thực thi trên JVM, được dịch sang chính mã máy của Hệ điều hành đó.
JVM cung cấp một số tính năng như quản lý bộ nhớ, kiểm tra an toàn. Đồng thời còn thu gom rác để giúp các chương trình Java chạy hiệu quả và tin cậy. JVM tạo và quản lý các luồng (threads) trong ứng dụng Java để tăng khả năng xử lý đa luồng.
JVM là một phần quan trọng của nền tảng Java. Nó cho phép các chương trình chạy trên nhiều nền tảng khác nhau mà không phải thay đổi mã nguồn.
2. Java Virtual Machine hoạt động như thế nào?
Java Virtual Machine (JVM) hoạt động bằng cách thực thi mã bytecode được tạo ra từ mã nguồn Java bằng cách sử dụng quy trình sau:
- Biên dịch: Mã nguồn Java được biên dịch thành mã byte code bằng trình biên dịch Java (javac).
- Tải lên lưu trữ: Mã bytecode được tải lên lưu trữ và chờ để thực thi.
- Kiểm tra bytecode: Trước khi thực thi, JVM kiểm tra mã bytecode để đảm bảo tính toàn vẹn và an toàn của chương trình. Nếu có lỗi trong mã bytecode, JVM sẽ báo lỗi và chương trình sẽ không thực thi.
- Thực thi: Mã bytecode được thực thi bởi JVM. JVM đọc từng bytecode trong chương trình Java và thực hiện các hành động tương ứng với bytecode đó. Nếu có lỗi xảy ra trong quá trình thực thi, JVM sẽ thông báo lỗi và dừng thực thi chương trình.
- Quản lý bộ nhớ: JVM quản lý bộ nhớ được sử dụng bởi chương trình Java. JVM sẽ tự động quản lý bộ nhớ và giải phóng bộ nhớ không sử dụng được.
- Thu gom rác: JVM sử dụng một tiến trình thu gom rác để giải phóng bộ nhớ đã không sử dụng được.
- Kết thúc chương trình: Khi chương trình kết thúc, JVM giải phóng tất cả bộ nhớ và tài nguyên được sử dụng bởi chương trình.
3. Các thành phần Kiến trúc bên trong của JVM
JVM có kiến trúc phức tạp với nhiều thành phần quan trọng bên trong. Các thành phần này bao gồm:
- Class Loader: Lớp Class Loader là thành phần đầu tiên của JVM. Nó có trách nhiệm tải các file .class vào bộ nhớ JVM để chúng có thể được thực thi. Class Loader được phân chia thành ba loại: Bootstrap Classloader, Extension Class Loader và System Class Loader.
- Runtime Data Area: Runtime Data Area là không gian bộ nhớ sử dụng bởi JVM để thực thi các chương trình Java. Nó được chia thành 5 khu vực:
- Method Area: Khu vực này lưu trữ các mã bytecode và các thông tin cần thiết cho các method trong chương trình Java.
- Heap: Heap là nơi lưu trữ các đối tượng Java được tạo ra bởi chương trình Java. Khu vực này cũng được sử dụng để quản lý bộ nhớ động trong Java.
- Java Stack: Java Stack lưu trữ các biến cục bộ và các giá trị ngăn xếp được sử dụng trong các method của chương trình Java.
- Native Method Stack: Đây là nơi lưu trữ các thông tin liên quan đến các method được thực thi bên ngoài JVM.
- PC Registers: Nó chứa các thông tin về trạng thái thực thi của thread.
- Execution Engine: Đây là thành phần thực thi mã bytecode. Nó có trách nhiệm biên dịch các mã bytecode thành mã máy để thực thi chương trình Java.
- Native Method Interface: Cung cấp cách kết nối chương trình Java với các thư viện và ứng dụng bên ngoài được viết bằng các ngôn ngữ khác như C, C++.
- Java Native Interface: Cung cấp cách để kết nối chương trình Java với các ứng dụng và thư viện bên ngoài.
- Security Manager: Đây là thành phần quản lý an ninh của JVM. Nó đảm bảo rằng các chương trình Java không được thực thi các hành động đe dọa an ninh hệ thống.
4. Quản lý bộ nhớ trong JVM thế nào?
JVM sử dụng một kỹ thuật quản lý bộ nhớ tự động được gọi là “Garbage Collection” (GC). GC quét các đối tượng đã cấp phát trong bộ nhớ. Nó tự động thu hồi các đối tượng không còn được sử dụng. Quá trình này hoàn toàn tự động và không cần lập trình viên.
GC sử dụng một số thuật toán để quản lý bộ nhớ. Các thuật toán này bao gồm:
- Mark and Sweep: Thuật toán này quét toàn bộ bộ nhớ và đánh dấu các đối tượng được sử dụng. Sau đó, nó thu hồi bộ nhớ của các đối tượng không được đánh dấu.
- Copying: Thuật toán này tách bộ nhớ thành hai phần. Một phần được sử dụng để lưu trữ các đối tượng đang được sử dụng. Còn lại được sử dụng để lưu trữ các đối tượng không còn sử dụng. Sau đó, sao chép các đối tượng đang sử dụng sang một phần của bộ nhớ . Chúng sẽ được giải phóng phần bộ nhớ còn lại.
- Generational: Thuật toán này sử dụng việc phân loại các đối tượng theo tuổi để quản lý bộ nhớ. Các đối tượng mới được tạo ra được lưu trữ trong một vùng bộ nhớ được gọi là “eden space”.
Sau đó, các đối tượng được chuyển sang vùng bộ nhớ “survivor space” khi sống sót qua một lần quét. Các đối tượng có tuổi cao hơn được chuyển sang vùng bộ nhớ “old generation”. Khi bộ nhớ “eden space” hoặc “survivor space” đầy, GC sẽ chuyển các đối tượng sang vùng bộ nhớ khác.
JVM cũng cung cấp một số cấu hình để tùy chỉnh quá trình GC. Ví dụ, bạn có thể chỉ định thời gian tối đa cho quá trình GC. Một cách khác là chọn các thuật toán khác nhau để quản lý bộ nhớ.
5. Nạp và thực thi file Java class trong JVM
Để nạp và thực thi một file Java class trong JVM, bạn cần thực hiện các bước sau:
Bước 1: Biên dịch file Java thành file Bytecode:
Bạn cần biên dịch file Java thành file bytecode, được lưu trữ trong file có đuôi “.class“. Bạn có thể sử dụng trình biên dịch Java (javac) để thực hiện việc này.
Ví dụ: Nếu bạn có một file Java tên là “MyClass.java”, bạn biên dịch bằng cách chạy lệnh trong command line:
javac MyClass.java
Bước 2: Thực thi file Bytecode
Khi đối tượng của class được tạo ra bạn tiến hành Thực thi file bytecode (phương thức main của class sẽ được thực thi). Các câu lệnh trong phương thức main sẽ được thực thi theo thứ tự.
Khi bạn chạy lệnh “java MyClass”, JVM sẽ nạp file bytecode “MyClass.class” vào. Nó sẽ thực thi phương thức main của class MyClass. Kết quả là chuỗi “Hello, world!” được in ra màn hình.
Bước 3: Nạp file bytecode
Sau khi file bytecode được tạo ra, bạn có thể Nạp file bytecode vào JVM bằng cách sử dụng lệnh “java”. Lệnh này sẽ nạp file bytecode vào JVM và tạo ra một đối tượng của class đó để thực thi.
Ví dụ: Nếu bạn đã biên dịch file MyClass.java thành file bytecode “MyClass.class”. Bạn có thể nạp nó vào JVM bằng cách chạy lệnh sau trong command line:
java MyClass
Lệnh này sẽ nạp file bytecode “MyClass.class” vào JVM và tạo ra một đối tượng của class MyClass để thực thi.
Hy vọng rằng những thông tin về Java Virtual Machine JVM là gì đã giúp bạn có cái nhìn tổng quan nhất. Hãy sử dụng nó hiệu quả trong lập trình. Nếu bạn còn bất kỳ thắc mắc hoặc muốn tìm hiểu về dịch vụ VPS, Dịch vụ Hosting, Server, hãy để lại bình luận ở bên dưới nhé! Chúng tôi sẽ cố gắng giải đáp sớm nhất.