Kích thước tối đa của một phương thức trong Java 7 và 8


80

Tôi biết rằng một phương thức không thể lớn hơn 64 KB với Java. Hạn chế khiến chúng tôi gặp sự cố với mã được tạo từ ngữ pháp JavaCC . Chúng tôi gặp sự cố với Java 6 và có thể khắc phục điều này bằng cách thay đổi ngữ pháp. Giới hạn đã được thay đổi cho Java 7 hay nó được lên kế hoạch cho Java 8?

Chỉ để làm cho nó rõ ràng. Tôi không cần một phương thức lớn hơn 64 KB. Nhưng tôi đã viết một ngữ pháp biên dịch theo một phương pháp rất lớn.


4
Tôi cũng gặp phải vấn đề tương tự khi cố gắng biên dịch một đoạn mã brainf ** k khổng lồ.
johnchen902

3
Không có thông tin nào ngược lại, tôi nghĩ có thể an toàn khi giả định rằng giới hạn này sẽ vẫn được thực thi trong Java 8 ... Tất nhiên, một tùy chọn khác (tốn kém) có thể là thay đổi công cụ ngữ pháp cho parboiled , điều này cho phép bạn viết ngữ pháp của bạn bằng Java thuần túy.
fge

4
có một cái nhìn tại này bài viết
Anirudha

7
Cá nhân tôi nghĩ rằng việc tạo ra các phương thức lớn như vậy là một lỗi trong JavaCC . Nó thực sự có thể phát tán mã của nó. Đặc biệt là xem xét rằng JVM chắc chắn không được xây dựng để tối ưu hóa các phương pháp khổng lồ như vậy.
Joachim Sauer

Câu trả lời:


58

Theo JVMS7 :

Thực tế rằng end_pc là độc quyền là một sai lầm lịch sử trong thiết kế của máy ảo Java: nếu mã máy ảo Java cho một phương thức dài chính xác là 65535 byte và kết thúc bằng một lệnh dài 1 byte, thì lệnh đó không thể được bảo vệ bởi một trình xử lý ngoại lệ. Người viết trình biên dịch có thể khắc phục lỗi này bằng cách giới hạn kích thước tối đa của mã máy ảo Java được tạo cho bất kỳ phương thức nào, phương thức khởi tạo phiên bản hoặc trình khởi tạo tĩnh (kích thước của bất kỳ mảng mã nào) là 65534 byte.

Nhưng đây là về Java 7. Không có thông số kỹ thuật cuối cùng cho Java 8, vì vậy không ai (ngoại trừ các nhà phát triển của nó) có thể trả lời câu hỏi này.

UPD (2015-04-06) Theo JVM8 thì nó cũng đúng với Java 8.


2
Thực sự có một "lỗi" trong Java mà nó vẫn chưa được sửa? Có thể là một hạn chế nặng nề, đặc biệt đối với tình huống LaurentG.
Francesco Belladonna

3
@ Fire-Dragon-DoL Cuộc thảo luận được trích dẫn chỉ nói về phương pháp phải có độ dài nhỏ hơn một byte so với cách khác. Điều này là khá phi quan trọng. Giới hạn không phải do bất kỳ "lỗi" đơn giản nào như vậy: nó nằm trong thiết kế tổng thể của bytecode và để khắc phục nó sẽ cần phải thay thế toàn bộ.
Marko Topolnik

11

Câu hỏi hay. Như mọi khi, chúng ta nên vào nguồn để tìm câu trả lời ( "Đặc điểm kỹ thuật máy ảo Java®" ). Tuy nhiên, phần này không đề cập rõ ràng đến một giới hạn (cũng như thông số kỹ thuật máy ảo Java6), nhưng có phần lưu ý:

Số lượng biến cục bộ lớn nhất trong mảng biến cục bộ của khung được tạo khi gọi một phương thức (§2.6) được giới hạn ở 65535 kích thước của mục max_locals của thuộc tính Code (§4.7.3) cung cấp mã của và bằng cách lập chỉ mục biến cục bộ 16 bit của tập lệnh Máy ảo Java.

Chúc mừng,


5
OP yêu cầu “số lượng biến cục bộ lớn nhất” có cùng giá trị số, nhưng vẫn là một thứ hoàn toàn khác với “kích thước tối đa của một phương pháp”.
Holger

8

Nó không thay đổi. Giới hạn mã trong các phương thức vẫn là 64 KB trong cả Java 7 và Java 8.

Người giới thiệu:

  1. Từ Đặc điểm kỹ thuật máy ảo Java 7 ( 4.9.1 Các ràng buộc tĩnh ):

Các ràng buộc tĩnh đối với mã Máy ảo Java trong một tệp lớp chỉ định cách các lệnh Máy ảo Java phải được trình bày trong mảng mã và toán hạng của các lệnh riêng lẻ phải là gì.

Các ràng buộc tĩnh trên các hướng dẫn trong mảng mã như sau:

  • Mảng mã không được để trống, do đó, mục code_length không được có giá trị 0.
  • Giá trị của mục code_length phải nhỏ hơn 65536.
  1. Từ Đặc điểm kỹ thuật máy ảo Java 8 ( 4.7.3 Thuộc tính mã ):

Giá trị của mục code_length cung cấp số byte trong mảng mã cho phương thức này.

Giá trị của code_length phải lớn hơn 0 (vì mảng mã không được để trống) và nhỏ hơn 65536.


1

Andremoniy đã trả lời java 7một phần của câu hỏi này rồi, nhưng có vẻ như tại thời điểm đó, tôi đã sớm quyết định về việc này java 8nên tôi hoàn thành câu trả lời để bao gồm phần đó:

Trích dẫn từ jvms :

Thực tế rằng end_pc là độc quyền là một sai lầm lịch sử trong thiết kế của Máy ảo Java: nếu mã Máy ảo Java cho một phương thức dài chính xác là 65535 byte và kết thúc bằng một lệnh dài 1 byte, thì lệnh đó không thể được bảo vệ bởi một trình xử lý ngoại lệ. Người viết trình biên dịch có thể khắc phục lỗi này bằng cách giới hạn kích thước tối đa của mã Máy ảo Java được tạo cho bất kỳ phương thức nào, phương thức khởi tạo phiên bản hoặc trình khởi tạo tĩnh (kích thước của bất kỳ mảng mã nào) là 65534 byte.

Như bạn thấy, vấn đề lịch sử này dường như không được khắc phục ít nhất trong phiên bản này (java 8).


-1

Là một giải pháp thay thế và nếu bạn có quyền truy cập vào mã của trình phân tích cú pháp, bạn có thể sửa đổi nó để hoạt động trong bất kỳ giới hạn nào được trình biên dịch JVM áp đặt ... sửa đổi)

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.