Tài liệu Tìm hiểu về jvm (java virtual machine)

  • Số trang: 38 |
  • Loại file: DOCX |
  • Lượt xem: 1417 |
  • Lượt tải: 0
thucaothi349968

Tham gia: 25/12/2016

Mô tả:

Tìm hiểu về jvm (java virtual machine)
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI VIỆN ĐIỆN TỬ - VIỄN THÔNG .........****......... BÁO CÁO BÀI TẬP LỚN HỆ ĐIỀU HÀNH Đề tài: Tìm hiểu về JVM (Java Virtual Machine) Hà Nội 5/2016 LỜI GIỚI THIỆU Tìm hiểu JVM Java là một ngôn ngữ lập trình hướng đối tượng (OOP) và dựa trên các lớp (class). Khác với phần lớn ngôn ngữ lập trình thông thường, thay vì biên dịch mã nguồn thành mã máy hoặc thông dịch mã nguồn khi chạy, Java được thiết kế để biên dịch mã nguồn thành bytecode, bytecode sau đó sẽ được môi trường thực thi (runtime environment) chạy. Java được tạo ra với tiêu chí "Viết (code) một lần, thực thi khắp nơi" ("Write Once, Run Anywhere" (WORA)). Chương trình phần mềm viết bằng Java có thể chạy trên mọi nền tảng (platform) khác nhau thông qua một môi trường thực thi với điều kiện có môi trường thực thi thích hợp hỗ trợ nền tảng đó. Môi trường thực thi của Sun Microsystems hiện hỗ trợ Sun Solaris, Linux, Mac OS,FreeBSD & Windows. Ngoài ra, một số công ty, tổ chức cũng như cá nhân khác cũng phát triển môi trường thực thi Java cho những hệ điều hành khác như BEA, IBM, HP.... Trong đó đáng nói đến nhất là IBM Java Platform hỗ trợ Windows, Linux, AIX & z/OS. Java Virtual Machine (JVM) bản chất là một chương trình có thể thực thi các đoạn mã lập trình của Java, và đặc điểm của những chương trình viết bằng Java là đều có thể chạy trên bất kỳ môi trường nào, miễn là có cài máy ảo JVM trên đó. Việc này sẽ tạo một động lực rất lớn thúc đẩy việc dùng lại các phần mềm Java đã được viết trước đây và việc phát triển phần mềm trên iPhone và iTouch. Vai trò to lớn, tính thực dụng và các ứng dụng rộng rãi của JVM đã nhận được sự quan tâm sâu sắc của các kỹ sư, chuyên viên lập trình cũng như những người đam mê công nghệ. Song việc tìm hiểu và tiếp cận JVM gặp nhều khó khăn do chưa có nhiều tài liệu mô tả một cách chi tiết và rõ ràng. Cũng như thực tế có rất ít các trường đại học dạy về vấn đề này. Do đó qua tìm hiểu kết hợp sự hướng dẫn cũng như giúp đỡ của thầy Vũ Song Tùng, chúng em đã đưa ra một bản báo cáo một cách cơ bản về JVM. Hi vọng tài liệu này đóng góp một phần kiến thức cơ bản về JVM cho những ai muốn tìm hiểu. bản báo cáo này vẫn còn nhiều thiếu sót, chúng em mong có được sự đóng góp ý kiến cũng như phản biện của người đọc để hoàn thiện hơn Xin chân thành cảm ơn ! MỤC LỤC Page | 2 Tìm hiểu JVM LỜI GIỚI THIỆU.............................................................................................................2 I. Giới thiệu chung về Java Virtual Machine (JVM)............................................................5 1.1. Giới thiệu chung........................................................................................................................5 1.1.1. Giới thiệu Java Virtual Machine (JVM).........................................................5 1.1.2. Máy ảo Java là gì?............................................................................................5 1.1.3. Kiến trúc của máy ảo Java..............................................................................6 1.2. Phương thức thực thi...............................................................................................................8 1.2.1. Quản lý bộ nhớ và dọn rác..............................................................................8 1.2.2. Quá trình kiểm tra file .class...........................................................................8 II. Tìm hiểu chi tiết về các thành phần trong Java Virtual Machine(JVM).................9 2.1. Tìm hiểu về Java Memory..................................................................................9 2.3. Các Kiểu Dữ Liệu..............................................................................................30 2.4. Word Size...........................................................................................................33 2.5. Program Counter..............................................................................................33 2.6. Threads (luồng trong Java)..............................................................................34 2.7. Native Method Interface...................................................................................36 PHỤ LỤC.......................................................................................................................... 4 DANH SÁCH HÌNH VẼ.................................................................................................................4 DANH SÁCH BẢNG.......................................................................................................................4 TÀI LIỆU THAM KHẢO..............................................................................................38 PHỤ LỤC DANH SÁCH HÌNH VẼ Hình 1.1. Sơ đồ đơn giản về máy ảo Java………………………………….….…......7 Page | 3 Tìm hiểu JVM Hình 1.2. Sơ đồ bên trong của JVM………………..………………..……….…..…..7 Hình 2.1. Khu vực chia sẻ dữ liệu các thành phần…………...……..…….….……10 Hình 2.2. Hoạt động Stack trong JVM……………………..………….…….….….11 Hình 2.3. Mô tả một cách tiếp cận đối tượng của Heap…………………….…..…14 Hình 2.4. Một cách tiếp cận Object khác của Heap……….………………..….….15 Hình 2.5. Một cách tham chiếu đối tượng………………………….………..….….16 Hình 2.6. Đại diện của mảng trên Heap…………………………….………..….…17 Hình 2.7. Tham số phương thức trên phần biến địa phương của Java Stack..…20 Hình 2.8. Mô phỏng việc thêm 2 biến cục bộ……………………………….……...22 Hình 2.9. Mô phỏng hoạt động stack qua Ví Dụ………………………….….........23 Hình 2.10. Phân bố các khung hình từ ngăn xếp liền kề nhau…………….…...…24 Hình 2.11. Stack cho một thread khi Java gọi phương thức địa phương………...26 Hình 2.12. Các kiểu dữ liệu trong Java………………………………….….…...…31 DANH SÁCH BẢNG Bảng 2.1. Phạm vi các kiểu dữ liệu trong máy ảo Java………………………...….33 Page | 4 Tìm hiểu JVM I. Giới thiệu chung về Java Virtual Machine (JVM) 1.1. Giới thiệu chung 1.1.1. Giới thiệu Java Virtual Machine (JVM) Tất cả các chương trình muốn thực thi được thì phải được biên dịch ra mã máy. Mã máy của từng kiến trúc CPU của mỗi máy tính là khác nhau (tập lệnh mã máy của CPU Intel, CPU Solarix, CPU Macintosh … là khác nhau), vì vậy trước đây 1 chương trình sau khi được biên dịch xong chỉ có thể chạy trên 1 kiến trúc CPU cụ thể nào đó. Đối với Intel chúng ta có thể chạy các hệ điều hành như Microsoft Windows, Unix, Linux… Chương trình thực thi được trên Windows được biên dịch dưới dạng file có đuôi .EXE còn trên Linux thì được biên dịch dưới dạng file có đuôi .ELF, vì vậy trước đây 1 chương trình chạy trên Windows muốn chạy trên các hệ điều hành khác như Linux phải chỉnh sửa biên và biên dịch lại. Ngôn ngữ lập trình Java ra đời, nhờ vào máy ảo Java mà khó khăn trên được khắc phục. Một chương trình được viết bằng ngôn ngữ lập trình Java sẽ được biên dịch ra mã của máy ảo Java (mã Java bytecode). Sau đó máy ảo Java chịu trách nhiệm chuyển mã Java bytecode thành mã máy tương ứng. Sun Microsystem chịu trách nhiệm phát hiện các máy ảo Java chạy trên các hệ điều hành trên các kiến trúc CPU khác nhau. Máy ảo java được sinh ra với 3 mục đích chính:  Dịch mã java ra mã máy chạy được trên các hê ê điều hành khác nhau.  Tăng tốc đô ê.  Nâng cao đô ê bảo mâ tê và tránh virus phá source code. 1.1.2. Máy ảo Java là gì? Như đã biết, JVM bản chất là một chương trình có thể thực thi các đoạn mã lập trình của Java, và đặc điểm của những chương trình viết bằng Java là đều có thể chạy Page | 5 Tìm hiểu JVM trên bất kỳ môi trường nào, miễn là có cài máy ảo JVM trên đó. Việc này sẽ tạo một động lực rất lớn thúc đẩy việc dùng lại các phần mềm Java đã được viết trước đây và việc phát triển phần mềm trên iPhone và iTouch. Máy ảo là một phần mềm dựa trên cơ sở máy tính ảo. Nó có tập hợp các lệnh logic để xác định các hoạt động của máy tính.Người ta có thể xem nó như một hệ điều hành thu nhỏ. Nó thiết lập các lớp trừu tượng cho: Phần cứng bên dưới,hệ điều hành,mã đã biên dịch. Trình biên dịch chuyển mã nguồn thành tập các lệnh của máy ảo mà không phụ thuộc vào phần cứng cụ thể. Trình thông dịch trên mỗi máy sẽ chuyển tập lệnh này thành chương trình thực thi. Máy ảo tạo ra một môi trường bên trong để thực thi các lệnh bằng cách:  Nạp các file.class  Quản lý bộ nhớ  Dọn "rác" Việc không nhất quán của phần cứng làm cho máy ảo phải sử dụng ngăn xếp để lưu trữ các thông tin sau:  Các "Frame" chứa các trạng thái của các phương pháp.  Các toán hạng của mã bytecode  Các tham số truyền cho phương pháp  Các biến cục bộ Khi JVM thực thi mã, một thanh ghi cục bộ có tên "Program Counter" được sủ dụng. Thanh ghi này trỏ tới lệnh đang thực hiện. Khi cần thiết, có thể thay đổi nội dung thanh ghi để đổi hướng thực thi của chương trình. Trong trường hợp thông thường thì từng lệnh một nối tiếp nhau sẽ được thực thi. Một khái niệm thông dụng khác trong Java là trình biên dịch "Just In TimeJIT". Các trình duyệt thông dụng như Netscape hay IE đều có JIT bên trong để tăng tốc độ thực thi chương trình Java. Mục đích chính của JIT là chuyển tập lệnh bytecode thành mã máy cụ thể cho từng loại CPU. Các lệnh này sẽ được lưu trữ và sử dụng mỗi khi gọi đến. Page | 6 Tìm hiểu JVM 1.1.3. Kiến trúc của máy ảo Java Hình 1.1 là sơ đồ đơn giản về máy ảo Java Hình 1.1 Sơ đồ đơn giản về máy ảo Java Đầu tiên sẽ là biên dịch file.java sang file.class và được máy ảo Java chuyển hoá thành các mã máy tương ứng với các hệ điều hành tương ứng. Để tìm hiểu sâu hơn chúng ta đi vào sơ đồ nội bộ của 1 máy ảo Java Hình 1.2 Sơ đồ bên trong của Java Virtual Machine Page | 7 Tìm hiểu JVM Như trong hình ta thấy Java có 3 thành phần chính 1. 2. 3. Class Loader: Tìm kiếm và nạp các file.class vào vùng nhớ java Data Area: Vùng nhớ hệ thống cấp phát cho Java Virtual Machine Execution Engine: chuyển các lệnh của JVM trong file.class thành mã máy tương ứng với các hệ điều hành 1.2. Phương thức thực thi 1.2.1. Quản lý bộ nhớ và dọn rác Trong C, C++ hay Pascal người lập trình sử dụng phương pháp nguyên thủy để cấp phát và thu hồi bộ nhớ ở vùng " Heap". Heap là vùng bộ nhớ lớn được phân chia cho tất cả các Thread. Để quản lý Heap, bộ nhớ được theo dõi qua các danh sách sau: - Danh sách các vùng nhớ rảnh chưa cấp phát. - Danh sách các vùng đã cấp Khi có một yêu cầu về cấp phát bộ nhớ, hệ thống kiểm tra xem xét trong danh sách chưa cấp phát để lấy ra khối bộ nhớ đầu tiên có kích cỡ sát nhất. Chiến thuật cấp phát này giảm tối thiểu việc phân mảnh của Heap. "Coalescing" là kỹ thuật khác cũng giảm thiểu việc phân mảnh của Heap bằng cách gom lại các vùng nhớ chưa dùng liền nhau. Còn kỹ thuật sắp xếp lại các phần đã dùng để tạo vùng nhớ lớn hơn gọi là "Compaction" Java sử dụng hai Heap riêng biệt cho cấp phát vùng nhớ tĩnh và vùng nhớ động. Một Heap(Heap tĩnh) chứa các định nghĩa về lớp, các hằng và danh sách các phương pháp. Heap còn lại(Heap động) được chia làm hai phần được cấp phát theo hai chiều ngược nhau. Một bên chứa đối tượng còn bên kia chứa con trỏ trỏ đến đối tượng đó. "Handle" là cấu trúc bao gồm hai con trỏ. Một trỏ đến bảng phương pháp của đối tượng, con trỏ thứ hai trỏ đến chính đối tượng đó. Chú ý rằng khi "compaction" cần cập nhập lại giá trị con trỏ của cấu trúc" Handle". Thuật toán dọn rác có thể áp dụng cho các đối tượng đặt trong Heap động. Khi có yêu cầu về bộ nhớ, trình quản lý Heap trước tiên kiểm tra danh sách bộ nhớ chưa cấp phát. Nếu không tìm thấy khối bộ nhớ nào phù hợp(về kích cỡ) thì trình dọn rác sẽ được kịch hoạt khi hệ thống rảnh. Nhưng khi đòi hỏi bộ nhớ cấp bách thì trình dọn rác sẽ được kích hoạt ngay. Page | 8 Tìm hiểu JVM Trình dọn rác gọi hàm Finalize trước khi dọn dẹp đối tượng. Hàm này sẽ dọn dẹp các tài nguyên bên ngoài như các file đang mở. Công việc này không được trình dọn rác thực thi. 1.2.2. Quá trình kiểm tra file .class Việc kiểm tra được áp dụng cho tất cả các file .class sắp được nạp lên bộ nhớ để đảm bảo tính an toàn. Trình "Class Loader" sẽ kiểm tra tất cả các file .class không phụ thuộc hệ điều hành với mục đích giám sát sự tuân thủ các nghi thức để phát hiện các file ,class có nguy cơ gây hư hỏng đến bộ nhớ, hệ thống file cục bộ, mạng hoặc hệ điều hành. Quá trình kiểm tra sẽ xem xét đến tính toàn vẹn toàn cục của lớp. File .class bao gồm ba phần logic là: 1. Byecode 2. Thông tin về Class như phương pháp, giao diện và các giá trị được tập hợp trong quá trình biên dịch. 3. Các thuộc tính về lớp. Các thông tin của file . class được xem xét riêng rẽ trong các bảng như sau:  Bảng file chứa các thuộc tính  Bảng Method chứa các hàm của class  Bảng Interface chứa các giao diện và các hằng số Quá trình kiểm tra file .class được thực hiện ở bốn mức: • Mức đầu tiên thực hiện việc kiểm tra cú pháp để đảm bảo tính cấu trúc và tính toàn vẹn cú pháp của file .class được nạp. • Mức thứ hai sẽ xem xét file.class để đảm bảo các file này không vi phạm các nguyên tắc về sự nhất quán ngữ nghĩa. • Mức thứ ba sẽ kiểm tra bytecode. Trong bước này các thông tin so sánh sẽ là số thông số truyền của hàm, khả năng truy xuất sai chỉ số của mảng, chuỗi, biểu thức. • Mức thứ tư sẽ kiểm tra trong thời gian thực thi để giám sát các việc còn lại mà ba bước trên chưa làm. Ví dụ như liên kết tới các lớp khác trong khi thực thi, hay kiểm tra quyền truy xuất. Nếu mọi điều thỏa mãn, lớp sẽ được khởi tạo. Page | 9 Tìm hiểu JVM II. Tìm hiểu chi tiết về các thành phần trong Java Virtual Machine (JVM) 2.1. Tìm hiểu về Java Memory Mỗi khi máy ảo java (JVM) chạy một chương trình, nó cần bộ nhớ để lưu trữ nhiều thứ bao gồm cả byte code và các thông tin nó lấy từ các file nạp, đối tượng chương trình được khởi tạo, các tham số, các giá trị trả lại, các biến địa phương và các kết quả trung gian trong quá trình tính toán. Các máy ảo Java nó tổ chức bộ nhớ thành nhiều vùng dữ liệu theo thời gian. Mặc dù khu vực vùng dữ liệu đó tồn tại trong một số hình thức của máy ảo java, đặc điểm của chúng là khá trừu tượng. Mỗi vùng nhớ có một cách tổ chức khác nhau giúp nhà thiết kế lựa chọn để triển khai công việc. Một số vùng nhớ được truy cập được từ mọi thành phần nhưng có những vùng nhớ thì không. Mỗi khi JVM nạp một file class nó sẽ phân tích thông tin về các loại dữ liệu nhị phân chứa trong file class đó. Nó sẽ đặt các thông tin này vào 1 vùng nhớ method area. Khi máy ảo hoạt động tất cả các đối tượng (object) sẽ được lưu vào vùng nhớ Heap. Hình 2.1 Khu vực chia sẻ dữ liệu các thành phần Mỗi thread xuất hiện nó được ghi vào 1 thanh ghi pc(chương trình đếm) và Java Stack. Nếu thread đang thực thi một phương thức của Java (không phải là phương thức địa phương) giá trị của thanh ghi pc chỉ lệnh kế tiếp được thực thi. Mỗi thread Java stack được lưu trữ trạng thái của Java (không có nguồn gốc) phương pháp gọi cho Java. Trạng thái của phương pháp gọi Java bao gồm: các biến tại địa phương, các biến Page | 10 Tìm hiểu JVM của nó được dẫn, các giá trị trả về (nếu có) và các giá trị trung gian trong quá trình thực hiện. Các trạng thái của phương thức gọi được lưu trữ phụ thuộc vào stack địa phương, hoặc các khu vực bộ nhớ thực hiện các phụ thuộc khác. Các Java Stack bao gồm các khung stack (khung). Một khung Stack chứa các trạng thái của một chương trình gọi Java. Khi có một thread gọi một phương pháp nào đó các máy ảo đẩy khung mới của chủ đề đó lên Java Stack. Khi chương trình này được chạy xong máy ảo tiến hành loại bỏ khung của phương thức đó. Các máy ảo Java không có các thanh ghi để lưu các giá trị trung gian. Các tập lệnh sử dụng chính Stack để lưu các giá trị trung gian. Cách làm này được thực hiện bởi các nhà thiết kế Java nhằm làm cho máy ảo Java được nhỏ gọn nhất để tạo điều kiện có thể cài đặt sử dụng trên các kiến trúc nhỏ. Ngoài ra các kiến trúc stack dựa trên các tập lệnh của máy ảo java tạo điều kiện làm việc tối ưu hoá thực hiện bằng cách just-in-time và trình biên dịch hoạt động ở thời gian chạy trong khi thực thi máy ảo. Hình 2.2 Hoạt động Stack trong JVM Page | 11 Tìm hiểu JVM Hình 2.2 là một hình ảnh thể hiện một trường hợp của máy ảo có 3 thread được thực hiện trong đó có một thread 3 là phương thức địa phương. Khung stack cho phương thức thực thi được hiện thi trong màu sáng. Đối với một Thread đang được thực hiện một phương thức của Java , thanh ghi Pc chỉ lệnh kế tiếp được thực thi. Trong hình 2.2 cũng như vậy thanh ghi pc được thể hiện trong một màu sáng. Bởi về thread 3 được thực hiện là một phương thức bản địa, các nội dung thanh ghi pc của nó – là màu tối (không xác định). 2.1.1. Bộ nhớ Heap Bất cứ một lớp hay một mảng nào được tạo ra trong quá trình chạy của máy ảo Java, bộ nhớ để lưu trữ tất cả các đối tượng là Heap. Java có chương trình chạy riêng biệt nên không thể có việc hai chương trình Java khác nhau lại sử dụng chung một dữ liệu, nhưng hai chủ đề trong cùng một ứng dụng có thể xung đột dữ liệu đó là việc bạn phải quan tâm đến việc đồng bộ hoá và tiếp cận đa luồng cho các đối tượng sử dụng trong chương trình Java của bạn. Các máy ảo Java cấp phát heap cho các đối tượng mới nhưng không có hỗ trợ phương thức cho người sử dụng giải phóng nó. Thông thường các máy ảo Java sẽ sử dụng bộ thu dọn rác để quản lý Heap a) Bộ thu dọn rác Chức năng chính của chương trình là lấy lại các vùng nhớ đang được sử dụng bời các đối tượng mà không còn được tham chiếu đến nữa khi JVM đang hoạt động. Nó cũng có thể di chuyển các ứng dụng hay các đối tượng chạy để giảm phân mảnh. Có thể bộ thu dọn rác hoạt động không đúng đặc điểm kỹ thuật của máy ảo Java. Các đặc điểm kỹ thuật chỉ yêu cầu thực hiện quản lý Heap riêng của mình theo một số phương pháp. Các đặc điểm kỹ thuật của máy ảo Java không nói có bao nhiêu bộ nhớ phải được sử dụng để có sẵn đối tượng cho chương trình đang chạy. Nó không nói làm thế nào để quản lí thực thi bộ nhớ Heap của nó, nó nói với các nhà thực hiện là chương trình sẽ được cấp phát bộ nhớ nhưng không giải phóng nó. Page | 12 Tìm hiểu JVM Không có kỹ thuật thu dọn nào được quyết định bởi các đặc điểm kỹ thuật của máy ảo Java. Nhà thiết kế sử dụng bất cứ kỹ thuật nào mà họ cho là phù hợp với mục tiêu và với những hạn chế về trình độ của họ. Khi một máy ảo cần một bộ nhớ cho một đối tượng mới, nó có thể làm mất dữ liệu từ Heap mà đối tượng đang cư trú. Việc thu dọn rác và giải phóng bộ nhớ bị quản lí bởi các đối tượng unreferenced có thể chăm sóc việc tìm kiếm và giải phóng. Triển khai cho phép người sử dụng hay lập trình có thể dễ dàng xác định 1 kích thước ban đầu cho Heap. b) Các đối tượng (Object) Các đặc điểm kỹ thuật của máy ảo java là im các đối tượng trên Heap. Đối tượng đại diện - một khía cạnh của thiết kế tổng thể - là quyết định của các nhà thiết kế thực hiện. Các dữ liệu chính phải bằng cách nào đó được đại diện cho mỗi đối tượng là các biến được khai báo trong các class của đối tượng và tất cả các superclasses của nó. Cho một tham chiếu đối tượng, các máy ảo phải nhanh chóng xác định vị trí các dữ liệu mẫu cho đối tượng. Ngoài ra phải có một số cách để truy cập dữ liệu lớp của đối tượng(được lưu trữ trong khu vực phương thức) cho tham chiếu đến đối tượng. Vì lý do này cấp phát bộ nhớ cho một đối tượng thường bao gồm một số loại con trỏ vào khu vực phương thức. Một thiết kế Heap có thể chia heap ra làm hai thành phần : Một khu xử lý và một khu đối tượng. Một tham chiếu đối tượng là một con trỏ có nguồn gốc từ một khu xử lý. Một khu xử lý có hai thành phần: một con trỏ đến đối tượng mẫu trong khu đối tượng và một con trỏ đế dữ liệu mẫu ở khu phương thức. Ưu điểm của hệ thống này là làm cho nó dễ dàng chống lại việc phân mảnh Heap. Khi các máy ảo di chuyển đối tượng ra một vị trí mới trong khu đối tượng nó chỉ việc trỏ đến nơi mới của đối tượng. Nhưng bất lợi của phương pháp này là mỗi một lần truy cập vào dữ liệu lại yêu cầu sử dụng 2 con trỏ. Hình ảnh sau đây thể hiện rõ ràng cách hoạt động của phương pháp này. Page | 13 Tìm hiểu JVM Hình 2.3 Mô tả cách tiếp cận đối tượng của Heap Một thiết kế khác là làm cho đối tượng tham chiếu một con trỏ có nguồn gốc từ một gói dữ liệu đã có dữ liệu sẵn. Cách tiếp cận này đòi hỏi dereferencing chỉ có một con trỏ để truy cập dữ liệu. Khi các máy ảo di chuyển đối tượng dẫn đến việc bị phân mảnh Heap, nó phải cập nhập mỗi tham chiếu đến đối tượng mà bất cứ nơi nào trong khu vực dữ liệu thời gian chạy. Cách tiếp cận này được thể hiện như sau. Page | 14 Tìm hiểu JVM Hình 2.4 Một cách tiếp cận Object khác của Heap Các máy ảo cần nhận được đối tượng tham chiếu đến lớp kiểu dữ liệu của đối tượng đó vì nhiều lý do. Khi một chương trình cố gắng để một đối tượng tham chiếu đến một kiểu khác, các máy ảo phải kiểm tra xem các loại đang được tham chiếu đến là class của đổi tượng tham chiếu hoặc là một trong các siêu kiểu của nó. Nó phải được kiểm tra khi một chương trình được chạy hay một instanceof hoạt động . Trong cả hai trường hợp, các máy ảo phải chọn lựa phương pháp nào để gọi không dựa trên tham số nhưng trên lớp của đối tượng. Để làm điều này nó phải có quyền một lần nữa truy cập vào các class dữ liệu nhất định chỉ có 1 tham chiếu đến đối tượng. Một cách một thực hiện có thể kết nối với phương thức để đối tượng được tham chiếu được hiển thị trong Hình 2.5 con số này cho thấy rằng con trỏ giữ cùng với các dữ liệu ví dụ cho từng đối tượng điểm đến một cấu trúc đặc biệt. Cấu trúc đặc biệt này có 2 phần  Một con trỏ có đầy đủ dữ liệu cho lớp đối tượng Page | 15 Tìm hiểu JVM  Bảng các phương thức cho các đối tượng bảng phương thức là một mảng của con trỏ đến dữ liệu cho mỗi phương thức. Các dữ liệu được trỏ đến bởi bảng phương thức bao gồm: o Các kích thước của toán hạng Stack và biến địa phương của phương thức ngăn xếp o ByteCode của phương thức o Bảng các giá trị ngoại lệ Điều này tạo đầy đủ thông tin để máy ảo gọi phương thức. Hình 2.5 Một cách tham chiếu đến đối tượng c) Đại diện mảng Trong Java mảng là đối tượng đầy đủ. Giống như đối tượng mảng cũng được lưu trữ trên Heap. Cũng như đối tượng các nhà thiết kế thực hiện có thể quyết định cách mà họ đại diện cho mảng trên heap. Mảng có class liên quan đến class của chúng giống như bất kỳ đối tượng khác. Tất cả các mảng có cùng kích thước và cùng loại sẽ cùng một lớp. Chiều dài của một Page | 16 Tìm hiểu JVM mảng (hay là độ dài kích thước của mảng đa chiều) không đóng vai trò nào trong việc thành lập nên lớp mảng. Chiều dài của một mảng coi như là một phần dữ liệu của mảng Hình 2.6 Đại diện của mảng trên Heap Các dữ liệu lưu trữ trên heap cho mỗi mảng là chiều dài của mảng, mảng dữ liệu, và một số loại tham số lớp của mảng. Cho một tham chiếu đến mảng, các máy ảo phải có khả năng xác định độ dài của mảng, để có được và cài đặt các phần tử của nó bằng chỉ số(kiểm tra để chắc chắn không vượt quá giới hạn) và để gọi bất kỳ một phương thức kê khai nào của đối tượng các lớp cha trực tiếp của tất cả các mảng. 2.2.2 Stack trong Java Khi một thread được đưa ra, các máy ảo Java tạo ra một Java Stack mới cho thread. Như đã đề cập trước đó một Stack lưu trữ trạng thái của một thread trong khung rời rạc. Các máy ảo Java chỉ thực hiện hai hoạt động trực tiếp trên Stack: Đẩy và Bật khung Các phương thức đang được thực hiện bởi một thread là phương thức hiện hành. Các khung stack cho các phương thức tại thời điểm là phương thức hiện tại. Các lớp chứa các phương thức hiện tại là lớp hiện tại và khu chứa các lớp hiện tại gọi là khu hiện tại. Khi thực hiện một phương thức các máy ảo theo dõi các lớp hiện tại và Page | 17 Tìm hiểu JVM các khu hiện tại. Khi máy ảo gặp hướng dẫn hoạt động trên các dữ liệu được lưu trữ trên các khung stack, nó thực hiện hoạt động trên khung hiện tại. Khi một thread gọi một phương thức Java, máy ảo tạo ra và đẩy một khung mới vào thread của Java Stack. Khung mới này sau đó trở thành nhưng khung hiện tại. Phương thức thực hiện, nó sử dụng khung hình để lưu trữ các thông số, các biến địa phương, tính toán trung gian và các dữ liệu khác. Một phương thức có thể hoàn thành bằng một trong hai cách. Nếu một phương thức hoàn thành bằng cách quay lại nó được cho là hoàn thành bình thường. Nhưng nếu kết thúc bằng cách ném ra một ngoại lệ nó được cho là hoàn thành đột ngột. Khi một phương thức hoàn thành cho dù là bình thường hay đột ngột các Java pops của máy ảo sẽ loại bỏ khung của khương thức ra khỏi Java Stack. Các khung hình cho các phương thức trước đó sẽ trở thành khung hiện tại. Tất cả dữ liệu trên một thread của Java Stack là dựa trên một thread nào đó. Không có cách nào để thread truy cập cũng như thay đổi Stack Java của một thread khác. Bởi vì điều này bạn không bao giờ phải lo lắng đồng bộ hoá luồng truy cập đến biến địa phương trong chương trình của bạn. Một khi thread gọi một phương thức biến cục bộ của phương thức được lưu trữ trong một khung trên thread theo Java Stack. Chỉ có phương thức của thread mới truy cập được vào biến địa phương trên thread đó. Cũng giống như các phương thức và heap, Java stack và khung stack không phải được tiếp giáp trong bộ nhớ. Khung có thể được phân bổ trên một Stack tiếp giáp hoặc trên heap hoặc cả hai. Các cấu trúc dữ liệu thực tế được sử dụng đại diện cho stack Java và khung Stack là quyết định của người thiết kế thực hiện. Triển khai có thể cho phép người sử dụng hoặc lập trình xác định một kích thước ban đầu cho Stack Java cũng như các giá trị kích thước max min. a) The Stack Frame (Khung stack) Các khung stack có 3 phần: các biến địa phương, toán hạng stack và khung dữ liệu. Các kích thước của các biến địa phương và toán hạng stack phụ thuộc vào nhu cầu của từng phương thức riêng lẻ. Các kích thước này được xác định tại thời điểm Page | 18 Tìm hiểu JVM biên dịch và đưa vào class dữ liệu cho từng phương thức. Kích thước của khung dữ liệu là sự phụ thuộc Khi máy ảo Java chạy sẽ là một phương thức Java, nó sẽ kiểm tra class dữ liệu để xác định số lượng các từ theo yêu cầu của phương thức trong các biến địa phương và toán hạng stack. Nó tạo ra một khung stack có kích thước thích hợp và đẩy vào Stack Java. b) Các biến địa phương Phần biến địa phương của stack frame Java được tổ chức như một mảng số không dựa trên các từ. Sử dụng một giá trị từ biến địa phương cung cấp một chỉ số vào mảng zero-based. Giá trị kiểu int, float, reference và returnAddress chiếm một ô trong mảng các biến địa phương. Giá trị kiểu byte, short và char được chuyển sang int trước khi lưu vào biến địa phương. Giá trị của kiểu long và double chiếm 2 mục liên tiếp trong mảng. Phần biến cục bộ chứa các thông số của một số phương thức và các biến địa phương. Trình biên dịch đặt các tham số vào mảng biến địa phương đầu tiên theo thứ tự chúng được khai báo.Hình 2.7 cho thấy phần biến địa phương trong 2 phương pháp. Page | 19 Tìm hiểu JVM Hình 2.7 Tham số phương thức trên phần biến địa phương của Java Stack Lưu ý rằng hình 2.7 cho thấy các tham số đầu tiên trong các biến địa phương cho runInstanceMethod() là kiểu reference mặc dù không có các tham số như vậy xuất hiện trong mã nguồn. Phương thức sử dụng thông tin này để truy cập các dữ liệu thể hiện các đối tượng trên đó. Như bạn có thể thấy bằng cách nhìn vào các biến cục bộ của runClassMethod() trong trong hình 2.7, các phương thức lớp không nhận được ẩn này. Phương thức Class không được gọi trên đối tượng. Bạn có thể không trực tiếp truy cập vào các biến cá thể của một class từ một phương thức vì không có sự kết hợp với các phương thức gọi. Cũng lưu ý rằng các loại byte, short, char và boolean trong mã nguồn mở trở thành int s trong biến địa phương. Điều này cũng đúng với các toán hạng stack. Như đã đề cập trước đó, boolean là loại không được hỗ trợ trong máy ảo Java. Trình biên dịch luôn luôn sử dụng int s để đại diện cho giá trị boolean trong các biến địa phương hay các toán hạng stack. Các kiểu byte, short và char tuy được hỗ trợ trực tiếp bởi máy ảo Java. Chúng có thể được lưu trữ trên heap như các biến cá thể hoặc các phần tử mảng hoặc trong khu vực như phương thức lớp. Khi được đặt vào biến địa phương hoặc các toán hạng stack thì các biến kiểu byte short hay char cũng được chuyển thành int s. Page | 20
- Xem thêm -