जावा 7 और 8 में एक विधि का अधिकतम आकार


82

मुझे पता है कि जावा के साथ एक विधि 64 KB से बड़ी नहीं हो सकती। सीमा हमें जावासीसी व्याकरण से उत्पन्न कोड की समस्याओं का कारण बनती है । हमें जावा 6 की समस्या थी और व्याकरण को बदलकर इसे ठीक करने में सक्षम थे। क्या जावा 7 के लिए सीमा बदल दी गई है या यह जावा 8 के लिए योजनाबद्ध है?

बस इसे स्पष्ट करने के लिए। मुझे 64 KB से बड़ी विधि की आवश्यकता नहीं है। लेकिन मैंने एक व्याकरण लिखा जो बहुत बड़ी विधि से संकलित है।


4
मुझे उसी समस्या का सामना करना पड़ा जब मैंने एक विशाल ब्रेनफ ** के कोड को संकलित करने की कोशिश की।
johnchen902

3
इसके विपरीत कोई जानकारी नहीं देते हुए, मुझे लगता है कि यह मान लेना सुरक्षित है कि यह सीमा अभी भी जावा 8 में लागू होगी ... बेशक, एक और (महंगा) विकल्प parboiled के लिए व्याकरण इंजन को बदलने के लिए हो सकता है , जो आपको अनुमति देता है शुद्ध जावा में अपने व्याकरण लिखें।
फेज

4
इस लेख पर एक नजर
अनिरुद्ध

7
व्यक्तिगत रूप से मुझे लगता है कि इस तरह के बड़े तरीकों का निर्माण जावासीसी में एक बग है । यह वास्तव में अपने कोड को फैलाने में सक्षम होना चाहिए। विशेष रूप से यह देखते हुए कि जेवीएम निश्चित रूप से ऐसे विशाल तरीकों के अनुकूलन के लिए नहीं बनाया गया है।
जोकिम सॉयर

जवाबों:


58

JVMS7 के अनुसार :

तथ्य यह है कि end_pc अनन्य है जावा वर्चुअल मशीन के डिजाइन में एक ऐतिहासिक गलती है: यदि किसी विधि के लिए जावा वर्चुअल मशीन कोड ठीक 65535 बाइट्स है और एक निर्देश के साथ समाप्त होता है जो 1 बाइट लंबा है, तो उस निर्देश को संरक्षित नहीं किया जा सकता है एक अपवाद हैंडलर द्वारा। एक कंपाइलर लेखक 65534 बाइट्स के लिए किसी भी विधि, उदाहरण इनिशियलाइज़ेशन विधि, या स्टैटिक इनिशियलाइज़र (किसी भी कोड ऐरे के आकार) के लिए उत्पन्न जावा वर्चुअल मशीन कोड के अधिकतम आकार को सीमित करके इस बग के आसपास काम कर सकता है।

लेकिन यह के बारे में है Java 7जावा 8 के लिए कोई अंतिम चश्मा नहीं है, इसलिए कोई भी (इसके डेवलपर्स को छोड़कर) इस सवाल का जवाब नहीं दे सका।

UPD (2015-04-06) JVM8 के अनुसार यह सही भी है Java 8


2
वास्तव में जावा में ऐसा "बग" है कि यह अभी भी तय नहीं है? एक भारी सीमा हो सकती है, स्पष्ट रूप से लॉरेंटग स्थिति के लिए।
फ्रांसेस्को बेलाडोना

3
@ फायर-ड्रैगन-डीओएल उद्धृत चर्चा केवल उस विधि के बारे में है जिसकी लंबाई एक बाइट से कम है, अन्यथा यह हो सकती थी। यह काफी सारहीन है। सीमा उस तरह से किसी भी साधारण "बग" के कारण नहीं है: यह बायटेकोड के समग्र डिजाइन में है और इसे ठीक करने के लिए इसे संपूर्णता में सम्मानजनक रूप से लिया जाएगा।
मार्को टोपोलनिक

11

अच्छा प्रश्न। हमेशा की तरह हमें उत्तर खोजने के लिए स्रोत पर जाना चाहिए ( "Java® Virtual Machine Specification" )। अनुभाग स्पष्ट रूप से एक सीमा का उल्लेख नहीं करता है (जैसा कि जावा 6 वीएम कल्पना), लेकिन कुछ हद तक चौकस:

किसी विधि के मंगलाचरण (of2.6) पर बनाए गए एक फ्रेम के स्थानीय चर सरणी में स्थानीय चर की अधिकतम संख्या कोड विशेषता (.74.7.3) के अधिकतम_लोकल्स आइटम के आकार तक सीमित है। विधि, और जावा वर्चुअल मशीन अनुदेश सेट के 16-बिट स्थानीय चर अनुक्रमण द्वारा।

चीयर्स,


5
"स्थानीय चर की सबसे बड़ी संख्या" में एक ही संख्यात्मक मूल्य होता है, लेकिन फिर भी "विधि के अधिकतम आकार" की तुलना में एक पूरी तरह से अलग बात है, ओपी ने पूछा।
Holger

8

यह नहीं बदला है। विधियों में कोड की सीमा अभी भी जावा 7 और जावा 8 दोनों में 64 केबी है।

संदर्भ:

  1. जावा 7 वर्चुअल मशीन विशिष्टता ( 4.9.1 स्टेटिक बाधाओं ) से:

जावा वर्चुअल मशीन कोड में जावा वर्चुअल मशीन कोड पर स्थिर बाधाएं निर्दिष्ट करती हैं कि कोड सरणी में जावा वर्चुअल मशीन निर्देशों को कैसे रखा जाना चाहिए और व्यक्तिगत निर्देशों के ऑपरेंड क्या होने चाहिए।

कोड सरणी में निर्देशों पर स्थिर अवरोध इस प्रकार हैं:

  • कोड सरणी खाली नहीं होनी चाहिए, इसलिए code_length आइटम का मान 0 नहीं हो सकता है।
  • Code_length आइटम का मान 65536 से कम होना चाहिए।
  1. जावा 8 वर्चुअल मशीन विशिष्टता ( 4.7.3 कोड विशेषता ) से:

Code_length आइटम का मान इस विधि के लिए कोड सरणी में बाइट्स की संख्या देता है।

Code_length का मान शून्य से अधिक होना चाहिए (क्योंकि कोड सरणी खाली नहीं होनी चाहिए) और 65536 से कम है।


1

अंदरमोनी ने java 7इस प्रश्न के भाग का उत्तर पहले ही दे दिया है, लेकिन लगता है कि उस समय यह जल्द ही तय होने वाला था java 8इसलिए मैं इस भाग को कवर करने का उत्तर पूरा करूंगा:

Jvms से उद्धरण :

तथ्य यह है कि end_pc अनन्य है जावा वर्चुअल मशीन के डिजाइन में एक ऐतिहासिक गलती है: यदि किसी विधि के लिए जावा वर्चुअल मशीन कोड ठीक 65535 बाइट्स है और एक निर्देश के साथ समाप्त होता है जो 1 बाइट लंबा है, तो उस निर्देश को संरक्षित नहीं किया जा सकता है एक अपवाद हैंडलर द्वारा। एक कंपाइलर लेखक 65534 बाइट्स के लिए किसी भी विधि, उदाहरण इनिशियलाइज़ेशन विधि, या स्टैटिक इनिशियलाइज़र (किसी भी कोड ऐरे के आकार) के लिए उत्पन्न जावा वर्चुअल मशीन कोड के अधिकतम आकार को सीमित करके इस बग के आसपास काम कर सकता है।

जैसा कि आप देख रहे हैं कि यह ऐतिहासिक समस्या कम से कम इस संस्करण में नहीं लगती है (जावा 8)।


-1

वर्कअराउंड के रूप में, और यदि आपके पास पार्सर कोड तक पहुंच है, तो आप इसे जेवीएम कंपाइलर द्वारा निर्धारित सीमा के अनुसार काम करने के लिए संशोधित कर सकते हैं ... (यह मानते हुए कि पार्सर कोड में भागों को खोजने के लिए इसे हमेशा के लिए नहीं लेना चाहिए। संशोधित करें)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.