जावा की बूलियन आदिम आकार को परिभाषित क्यों नहीं किया गया है?


111

जावा वर्चुअल मशीन विशिष्टता का कहना है बूलियन के लिए सीमित समर्थन है कि वहाँ आदिम प्रकार के।

बूलियन मूल्यों पर संचालन के लिए पूरी तरह से समर्पित जावा वर्चुअल मशीन निर्देश नहीं हैं। इसके बजाय, बूलियन मूल्यों पर काम करने वाली जावा प्रोग्रामिंग भाषा में अभिव्यक्तियाँ जावा वर्चुअल मशीन इंट डेटा प्रकार के मूल्यों का उपयोग करने के लिए संकलित की जाती हैं।

उपर्युक्त का तात्पर्य है (हालाँकि मैंने इसका गलत अर्थ निकाला हो सकता है) कि बुलियन पर काम करते समय इंट डेटा प्रकार का उपयोग किया जाता है, लेकिन यह 32 बिट मेमोरी कंस्ट्रक्शन है। यह देखते हुए कि एक बूलियन केवल 1 बिट जानकारी का प्रतिनिधित्व करता है:

  • एक बाइट, या छोटा क्यों है, इंट के बजाय बूलियन के लिए प्रॉक्सी के रूप में उपयोग नहीं किया जाता है?
  • किसी भी दिए गए JVM के लिए यह पता लगाने का सबसे विश्वसनीय तरीका क्या है कि बूलियन प्रकार को स्टोर करने के लिए कितनी मेमोरी का उपयोग किया जाता है?

जवाबों:


116

संक्षिप्त उत्तर: हां, बूलियन मानों को 32-बिट संस्थाओं के रूप में हेरफेर किया जाता है, लेकिन बूलियन के एरे प्रति तत्व 1 बाइट का उपयोग करते हैं।

लंबा उत्तर: जेवीएम एक 32-बिट स्टैक सेल का उपयोग करता है, जिसका उपयोग स्थानीय चर, विधि तर्क और अभिव्यक्ति मान रखने के लिए किया जाता है। 1 सेल से छोटे प्राइमिटिव्स को गद्देदार किया जाता है, 32 बिट्स (लॉन्ग और डबल) से बड़े प्राइमेट 2 सेल लेते हैं। यह तकनीक opcodes की संख्या को कम करती है, लेकिन इसमें कुछ अजीबोगरीब साइड-इफेक्ट्स (जैसे मास्क बाइट्स की जरूरत) हैं।

सरणियों में संग्रहीत प्राइमिटिव 32 बिट्स से कम का उपयोग कर सकते हैं, और एक सरणी से आदिम मूल्यों को लोड और स्टोर करने के लिए अलग-अलग ऑपकोड हैं। बूलियन और बाइट मान दोनों ही ऑप्सोड baloadऔर bastoreऑपकोड का उपयोग करते हैं , जिसका अर्थ है कि बूलियन एरे प्रति तत्व 1 बाइट लेते हैं।

जहां तक ​​इन-मेमोरी ऑब्जेक्ट लेआउट जाता है, यह "निजी कार्यान्वयन" नियमों के तहत कवर किया गया है , यह 1 बिट, 1 बाइट या किसी अन्य पोस्टर के रूप में नोट किया जा सकता है, जो 64-बिट डबल-शब्द सीमा से जुड़ा होता है। सबसे अधिक संभावना है, यह अंतर्निहित हार्डवेयर (32 या 64 बिट्स) के मूल शब्द आकार को लेता है।


जहां तक ​​बूलियंस का उपयोग करने वाले स्थान की मात्रा को कम करने के लिए: यह वास्तव में अधिकांश अनुप्रयोगों के लिए कोई समस्या नहीं है। स्टैक फ्रेम (स्थानीय चर और विधि तर्क को पकड़े हुए) बहुत बड़े नहीं होते हैं, और बड़ी योजना में किसी वस्तु में असतत बूलियन या तो बड़ा नहीं होता है। यदि आपके पास बहुत सारे बूलियन के साथ बहुत सी वस्तुएं हैं, तो आप बिट-फ़ील्ड का उपयोग कर सकते हैं जो आपके गेटर्स और सेटर्स के माध्यम से प्रबंधित होते हैं। हालाँकि, आप सीपीयू समय में एक दंड का भुगतान करेंगे जो संभवतः स्मृति में दंड से बड़ा है।


बूलियन / बाइट वर्ग के सदस्यों के लिए, क्या यह भी सच है, कि वे भी 4 बाइट्स हैं? वर्ग उदाहरण को स्टैक पर एक पूरे के रूप में आवंटित किया जाता है, इसलिए मैं कल्पना कर सकता हूं, जेवीएम को संभवतः बूलियन / बाइट सदस्य के प्रति 1 बाइट का उपयोग करना चाहिए और अंत में पूर्ण वर्ग उदाहरण के लिए 4-बाइट संरेखण करना चाहिए। ऐसा है क्या? (यदि आपके पास ऐसे संदर्भ हैं जो यह साबित करते हैं, तो कृपया साझा करें)
dma_k

@dma_k: मेरी प्रतिक्रिया के अनुसार, एक वर्ग उदाहरण का लेआउट कार्यान्वयन पर निर्भर है। हालांकि, ध्यान दें कि वर्ग के उदाहरण स्टैक में संग्रहीत नहीं हैं, वे ढेर पर संग्रहीत हैं (हालांकि आप JDK 7 "एस्केप एनालिसिस" से कुछ वस्तुओं को स्टैक से ढेर तक ले जाते हुए देखेंगे, ऐसा प्रतीत नहीं होता है; java.sun.com/javase/7/docs/technotes/guides/vm/…)
kdgregory

1
कभी-कभी पैकिंग वाले बूलियंस वास्तव में तेज हो सकते हैं। जब भी कैश आकार मायने रखता है, तो चीजों को पैक करना बेहतर हो सकता है। उदाहरण के लिए, 32 kB (L1 कैश आकार) के खंडों में एक खंडित प्राइम चलनी काम करता है जो एक गैर-सेग्ड छलनी की तुलना में तेज़ है। विखंडू के बीच कुछ ओवरहेड है और पैकिंग के साथ आप ओवरहेड को आठ बार कम भुगतान करते हैं। मैंने इसे अभी तक नहीं मापा है।
मातरिनस

7

वंशानुगत पदानुक्रम में कहीं एक एकल बूलियन 8 बाइट्स तक का उपयोग कर सकता है! यह पैडिंग के कारण है। अधिक जानकारी में पाया जा सकता है कि मेरे जावा ऑब्जेक्ट द्वारा कितनी मेमोरी का उपयोग किया जाता है? :

एक बूलियन कितनी खपत करता है, इस सवाल पर वापस आते हैं, हाँ यह कम से कम एक बाइट का उपभोग करता है, लेकिन संरेखण नियमों के कारण यह बहुत अधिक खपत कर सकता है। IMHO यह जानना अधिक दिलचस्प है कि एक बूलियन [] प्रति प्रविष्टि एक बाइट का उपभोग करेगा और एक बिट नहीं, साथ ही संरेखण के कारण और सरणी के आकार क्षेत्र के लिए कुछ ओवरहेड। ग्राफ एल्गोरिदम हैं जहां बिट्स के बड़े क्षेत्र उपयोगी होते हैं, और आपको यह जानने की आवश्यकता है कि, यदि आप बूलियन का उपयोग करते हैं [] आपको वास्तव में आवश्यक (लगभग 1 बाइट बनाम 1 बिट) की तुलना में लगभग 8 गुना अधिक मेमोरी की आवश्यकता है।


वैसे भी एक बूलियन [] का उपयोग कैसे किया जाएगा?
थॉमस जुंग

बूलियन [] एक मुखौटा के लिए इस्तेमाल किया जा सकता है। कभी-कभी एक बिटसेट बेहतर हो सकता है, क्योंकि इसके कुछ उपयोगी तरीके हैं।
माइकल मुन्से

5

नटशेल (ओ'रिली) में जावा के 5 वें संस्करण का कहना है कि एक बूलियन आदिम प्रकार 1 बाइट है। यह गलत हो सकता है, इस आधार पर कि ढेर की परीक्षा क्या दिखा रही है। मुझे आश्चर्य है कि अधिकांश जेवीएम के पास चर के लिए बाइट से कम आवंटन के साथ समस्या है।


3

बूलियन मैपिंग को 32 बिट सीपीयू को ध्यान में रखकर किया गया था। इंट वैल्यू में 32 बिट्स हैं इसलिए इसे एक ऑपरेशन में संसाधित किया जा सकता है।

यहाँ पीटर नॉरविग के जावा IAQ से एक समाधान दिया गया है: आकार को मापने के लिए निस्संदेह उत्तर दिए गए प्रश्न (कुछ अशुद्धताओं के साथ):

static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end =  runtime.freememory();
System.out.println("That took " + (start-end) + " bytes.");

चूंकि यह बातचीत प्राइमेटिक्स के बारे में है, इसलिए आपको यह परीक्षण करने में रचनात्मक होना होगा क्योंकि प्राइमेटिक्स ढेर में संग्रहीत नहीं किए जाते हैं जब तक कि वे एक उदाहरण या एक सरणी पर एक फ़ील्ड न हों। और उन में से कोई भी इस सवाल का जवाब नहीं देता है कि जावा वैसे भी स्टैक में कैसे स्टोर करेगा।
जेसी

2

सीपीयू एक विशिष्ट डेटा टाइप लंबाई पर काम करते हैं। 32 बिट सीपीयू के मामले में वे 32 बिट लंबे होते हैं और इसलिए आप जावा में 'इंट' कहते हैं। सीपीयू इसे संसाधित करने से पहले नीचे या ऊपर की सभी चीजों को इस लंबाई से भरा या विभाजित किया जाना चाहिए। इसमें अधिक समय नहीं लगता है, लेकिन यदि आपको बुनियादी कार्यों के लिए 1 के बजाय 2 सीपीयू चक्रों की आवश्यकता है, तो इसका मतलब दोगुना लागत / समय है।

यह युक्ति 32 बिट सीपीयू के लिए समर्पित है ताकि वे अपने मूल डेटाटाइप के साथ बूलियन को संसाधित कर सकें।

आप केवल एक ही यहाँ हो सकते हैं: गति या स्मृति - SUN ने गति के लिए निर्णय लिया।


1

बूलियन एक बिट जानकारी का प्रतिनिधित्व करता है, लेकिन इसका "आकार" कुछ ऐसा नहीं है जिसे ठीक से परिभाषित किया गया हो, सन जावा ट्यूटोरियल कहते हैं। बूलियन शाब्दिक में केवल दो संभावित मूल्य हैं जो सच्चे और झूठे हैं। देखें जावा डेटा प्रकार जानकारी के लिए।


-10

इस तरह से एक .java फ़ाइल क्यों न बनाएं:

Empty.java

class Empty{
}

और इस तरह एक वर्ग:

NotEmpty.java

class NotEmpty{
   boolean b;
}

उन दोनों को संकलित करें और एक .x संपादक के साथ .class फ़ाइलों की तुलना करें।


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