जावा में "कोड बहुत बड़ी" संकलन त्रुटि


94

क्या जावा में कोड के लिए कोई अधिकतम आकार है? मैंने 10,000 से अधिक लाइनों के साथ एक फ़ंक्शन लिखा। वास्तव में, प्रत्येक पंक्ति एक सरणी चर के लिए एक मान प्रदान करती है।

arts_bag[10792]="newyorkartworld";
arts_bag[10793]="leningradschool";
arts_bag[10794]="mailart";
arts_bag[10795]="artspan";
arts_bag[10796]="watercolor";
arts_bag[10797]="sculptures";
arts_bag[10798]="stonesculpture"; 

और संकलन करते समय, मुझे यह त्रुटि मिलती है: कोड बहुत बड़ा है

इसका समाधान कैसे किया जा सकता है?


9
मैं बस दंग रह गया ... ऐसा करने का एक बेहतर तरीका होना तय है।
थानोस पापनाथनसीउ

6
आपको वास्तव में इस प्रकार की चीज़ के लिए एक डेटाबेस को देखने की आवश्यकता है, जो कि एक संपत्ति फ़ाइल है।
पॉल व्हेलन

44
आप लोग खराब डिजाइन के लिए गरीब आदमी पर चिल्ला क्यों रहे हैं? हो सकता है कि ओपी ने कुछ कोड जनरेशन टूल द्वारा उस पागल विधि को प्राप्त किया हो।
वेबस्टर

14
मैं स्तब्ध हूं कि इन उथली आलोचनात्मक टिप्पणियों को इतने उभार मिले!
इवगेनी सर्गेव

7
जब आपके कंपाइलर प्री-जेनरेट सब कुछ कंपाइल समय पर कर सकते हैं तो आपके एप्लिकेशन स्टार्टअप ने कुछ टेक्स्ट फ़ाइल को पार्स करके बहुत समय क्यों बिताया है? यह खराब डिज़ाइन है यदि आप डेटा को फिर से जमा किए बिना बदलना चाहते हैं, या विधि को मैन्युअल रूप से लिखना चाहते हैं, लेकिन स्रोत कोड उत्पन्न करने पर यह बिल्कुल भी बुरा डिज़ाइन नहीं है। (कम से कम यदि आप इसे इस तरह से करते हैं कि वास्तव में कंपाइलर सरणी को प्रीजेनरेट करने की अनुमति देता है)।
गुंट्रम ब्लोम

जवाबों:


92

जावा वर्ग में एक एकल विधि, बाइटकोड के अधिकांश 64KB पर हो सकती है।

लेकिन आपको इसे साफ करना चाहिए!

.propertiesइस डेटा को संग्रहीत करने के लिए फ़ाइल का उपयोग करें , और इसके माध्यम से लोड करेंjava.util.Properties

आप इसे .propertiesअपने वर्गपथ पर फ़ाइल रखकर और उपयोग कर सकते हैं:

Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);

2
"कोई फर्क नहीं पड़ता कि आपके JDK / JVM का वास्तविक आकार क्या है?" क्या आप समझ रहे हैं कि यह सीमा तय नहीं है? क्योंकि यह वर्ग फ़ाइल प्रारूप विनिर्देश द्वारा तय और आवश्यक है।
जोकिम सॉर

1
मैं कहाँ .properties फ़ाइल पा सकते हैं
ट्रिनिटी

1
आप अपना स्वयं का निर्माण करते हैं और फिर उसे क्लासपाथ पर रख देते हैं
मार्क

3
मैंने आपके सुझाव का उपयोग नहीं किया, हालांकि मैं अगली बार इसे आज़माने के लिए उत्सुक हूं .. अब इस जानकारी को संग्रहीत करने के लिए एक डेटाबेस का उपयोग किया है, और 'शेष कोड को तदनुसार संशोधित किया है ..
ट्रिनिटी

1
मुझे खेद है कि यह एक बेवकूफ सवाल है, लेकिन .. यह कहाँ होना चाहिए। मेरा मतलब है, ठीक है, यह क्लासपाथ में है, लेकिन यह कहां है?
मिल्क

14

A पर 64K बाइट-कोड आकार सीमा है विधि

ऐसा कहने के बाद, मुझे w / रिचर्ड से सहमत होना होगा; आपको ऐसी विधि की आवश्यकता क्यों है जो बड़ी हो? ओपी में उदाहरण देते हुए, एक गुण फ़ाइल पर्याप्त होना चाहिए ... या यहां तक ​​कि यदि आवश्यक हो तो एक डेटाबेस।


4
कैसे दुश्मनी के बारे में? मैं एक ही मुद्दे के साथ बड़े पैमाने पर सेट करता हूं
टोबी

1
@ टोबै: कभी भी अपने आप को इस मुद्दे का सामना नहीं करना पड़ा। एसओ पर अन्य उपयोगकर्ताओं द्वारा पोस्ट किए गए हैं, हालांकि इसी मुद्दे के बारे में। उदाहरण के लिए - stackoverflow.com/questions/2546470 यह एक के लिए उत्पन्न .class फ़ाइल पर गौर करना श्रेयस्कर होगा enumदेखने के लिए
हर कोई

Enum इंस्टेंसेस (अर्थात ऑब्जेक्ट्स जो स्थिरांक का प्रतिनिधित्व करते हैं) क्लास 'स्टैटिक इनिशियलाइज़र' में बनाए जाते हैं, जो कि एक विधि है और इसमें समान सीमा होती है।
जूचन

मुझे वास्तव में जटिल वेब फॉर्म के लिए फ्रेमवर्क-जनरेट कोड के साथ एक ही समस्या का सामना करना पड़ा। समाधान घटकों में फार्म को विभाजित करने के लिए था, इसलिए प्रत्येक घटक के लिए उत्पन्न कोड भी विभाजित किया गया था।
सेबागरा

12

जावा वर्चुअल मशीन विनिर्देश के अनुसार , विधि का कोड 65536 बाइट्स से बड़ा नहीं होना चाहिए :

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

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

code_lengthcode[]विशेषता के आकार को परिभाषित करता है जिसमें एक विधि का वास्तविक बायटेकोड होता है:

codeसरणी कि विधि को लागू जावा वर्चुअल मशीन कोड की वास्तविक बाइट्स देता है।


7

यह थोड़ा पागलपन जैसा लगता है। क्या आप टेक्स्ट फ़ाइल, या किसी अन्य डेटा स्रोत से मूल्यों को पढ़कर सरणी को आरंभीकृत नहीं कर सकते हैं?


3
(क्योंकि downvoted) से कम एक कारण से यह जरूरत है कि क्यों ऐसी तकनीक बुरा है। एक अच्छे कारण के साथ आना आसान नहीं है।
इवगेनी सर्गेव

2

अपने कोड को रीफ़्रैक्टर करने का प्रयास करें। जावा में विधि के आकार की सीमा है।


1
यदि वह उस विधि में करता है तो एनालाइजेशन एक उचित विचार के रूप में सीवन नहीं करता है।
गेब्रियल Gabričerbák

2
उन्होंने कहा कि उनका बाकी कोड इस बात पर निर्भर करता है कि वह एक ऐरे हैं। इसलिए वह फ़ाइल / डेटाबेस से किसी अन्य विधि / फ़ैक्टरी में डेटा लोड करने की ज़िम्मेदारी पारित करने के लिए विधि को फिर से तैयार कर सकता है।
पदमराग

आप इस प्रकार की बकवास का सहारा लिए बिना बड़े सरणियों को बना और आरंभ कर सकते हैं; देखिए @ क्रिस का जवाब
स्टीफन C

रिफैक्टर - "सॉफ्टवेयर के कुछ गैर-गुणात्मक विशेषताओं को बेहतर बनाने के लिए अपने बाहरी कार्यात्मक व्यवहार को संशोधित किए बिना कंप्यूटर प्रोग्राम के स्रोत कोड को बदलने की प्रक्रिया।" अन्य उत्तर इससे अलग कैसे हैं?
पद्मराग

2

जैसा कि अन्य उत्तरों में बताया गया है कि एक विधि के लिए 64KB बाइटकोड सीमा है (कम से कम सन के जावा कंपाइलर में)

बहुत अधिक यह समझ में आता है कि उस विधि को और अधिक तरीकों से तोड़ने के लिए - प्रत्येक को सरणी से संबंधित कुछ सामान निर्दिष्ट करना (ऐसा करने के लिए एक ArrayList का उपयोग करने के लिए अधिक समझदारी हो सकती है)

उदाहरण के लिए:

public void addArrayItems()
{
  addSculptureItems(list);
  ...
}

public void addSculptureItems(ArrayList list)
{
  list.add("sculptures");
  list.add("stonesculpture");
}

वैकल्पिक रूप से आप आइटम को स्थैतिक संसाधन से लोड कर सकते हैं यदि वे किसी गुण फ़ाइल से तय किए गए हैं


सही उत्तर डेटा को डेटा और कोड को कोड के रूप में मानना ​​है।
मैल्कम

@ मैल्कम, यह स्पष्ट रूप से डेटा है, न कि कोड। आपकी टिप्पणी भ्रामक है, क्योंकि आपको जो नहीं करना चाहिए वह मिक्स डेटा और कोड है, लेकिन यहां वे मिश्रित नहीं हैं।
इवगेनी सर्गेव

मुझे लगता है कि यह एक अच्छा काम है। मैं इस समस्या को लगभग 7000k संदेशों के साथ कोड की 21k लाइनों के साथ पार करता हूं। मैं उन मार्गों के संदेशों को 7 फ़ंक्शन में xxx0 xxx1 xxx2 नाम से विभाजित करता हूं।
कांस्य पुरुष

2

मैं खुद इस समस्या में चला गया हूं। मेरे लिए काम करने वाला समाधान रिफ्लेक्टर था और विधि को अधिक प्रबंधनीय टुकड़ों में सिकोड़ना था। आपकी तरह, मैं लगभग 10K लाइन विधि से काम कर रहा हूं। हालांकि, स्थिर चर के साथ-साथ छोटे मॉड्यूलर कार्यों के उपयोग के साथ, समस्या का समाधान किया गया था।

लगता है कि एक बेहतर समाधान होगा, लेकिन जावा 8 का उपयोग करते हुए, कोई भी नहीं है ...


2

यह त्रुटि कभी-कभी किसी एकल फ़ंक्शन में बहुत बड़े कोड के कारण होती है ... उस त्रुटि को हल करने के लिए, उस फ़ंक्शन को कई कार्यों में विभाजित करें, जैसे

//Too large code function
private void mySingleFunction(){
.
.
2000 lines of code
}
//To solve the problem
private void mySingleFunction_1(){
.
.
500 lines of code
}
private void mySingleFunction_2(){
.
.
500 lines of code
}
private void mySingleFunction_3(){
.
.
500 lines of code
}
private void mySingleFunction_4(){
.
.
500 lines of code
}
private void MySingleFunction(){
mySingleFunction_1();
mySingleFunction_2();
mySingleFunction_3();
mySingleFunction_4();
}

1

आप अतिरिक्त डेटा स्थान के लिए अपने कोड के लिए स्थान बनाने के लिए एक और विधि जोड़ सकते हैं, आपके पास एक ऐसी विधि हो सकती है जो बड़ी मात्रा में डेटा स्थान ले रही हो। अपने तरीकों को विभाजित करने का प्रयास करें क्योंकि मेरे पास एक ही मुद्दा था और अपने जावा एंड्रॉइड कोड में उसी डेटा के लिए एक और अतिरिक्त विधि बनाकर इसे ठीक करें, मैंने ऐसा करने के बाद मुद्दा चला गया था।


यह एक उत्तर की तुलना में अधिक टिप्पणी है।
user3071284

0

मेरे पास एक एनुम है जो .java फ़ाइल का आकार 500KB से अधिक है। ग्रहण किसी कारण से इसका निर्माण कर सकता है; ग्रहण-निर्यात चींटी build.xml नहीं कर सकता। मैं इसे देख रहा हूं और इस पोस्ट को अपडेट करूंगा।


0

चूंकि विधियों के लिए एक आकार सीमा है और आप इस क्षण के रूप में अपने कोड को फिर से डिज़ाइन नहीं करना चाहते हैं, हो सकता है कि आप सरणी को 4-5 भागों में विभाजित कर सकते हैं और फिर उन्हें विभिन्न तरीकों में डाल सकते हैं। सरणी पढ़ने के समय, किसी श्रृंखला में सभी विधियों को कॉल करें। आपने यह जानने के लिए एक काउंटर बनाए रखा होगा कि आपने कितने इंडेक्स बनाए हैं।


0

यह एकल तरीकों के समाधान में सभी कोड के कारण है: कुछ और छोटे तरीके बनाएं, फिर यह त्रुटि हो जाएगी


0

ठीक है, शायद यह जवाब बहुत देर हो चुकी है लेकिन मुझे लगता है कि यह तरीका दूसरे तरीके से बेहतर है

उदाहरण के लिए, हमारे पास कोड में 1000 पंक्तियाँ डेटा हैं

  1. उन्हें तोड़ डाले

    private void rows500() {
         //you shoud write 1-500 rows here
    }
    
    private void rows1000() {
         you shoud write 500-1000 rows here
    }
  2. बेहतर प्रदर्शन के लिए अपने कोड में "if" डालें

    if (count < 500) {
        rows500();
    } else if (count > 500) {
        rows1000();
    }

मुझे उम्मीद है कि यह कोड आपकी मदद करेगा

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