जावा में बूलियन चर का आकार क्या है?


89

क्या कोई भी जावा में बूलियन का थोड़ा आकार बता सकता है ?


1
वही यहाँ पूछा गया है: stackoverflow.com/questions/1907318/…
dma_k

जवाबों:


41

यह वर्चुअल मशीन पर निर्भर है।


9
कुछ डॉक्स को इंगित करने के लिए देखभाल? मुझे यह विश्वास करना मुश्किल है कि एक बूलियन का आकार मशीन पर निर्भर है। इसका मतलब यह होगा कि एक बूलियन युक्त वर्ग के द्विआधारी प्रतिनिधित्व में विभिन्न वीएम में अलग-अलग आकार (और मेमोरी लेआउट) होंगे और इसका मतलब यह होगा कि वीएम संगत नहीं होंगे।
डेविड रॉड्रिग्ज - drieas

14
मुझे लगता है कि यह निहित था कि सवाल स्मृति में बूलियन चर के आकार का उल्लेख है, न कि एक वर्ग फ़ाइल में एन्कोड किए गए बूलियन चर के आकार का। मेमोरी में आकार सूर्य के प्रलेखन के अनुसार वीएम द्वारा भिन्न होता है। वर्ग फ़ाइल में आकार स्थिर है।
विलियम ब्रेंडल

3
@ DavidRodríguez-dribeas - जावा 1.1 के समय में सूर्य JVM ने बूलियन के लिए 4 बाइट्स का उपयोग किया जब एक उदाहरण या ऑटो संस्करण के रूप में संग्रहीत किया गया। इसने बाईटेकोड दुभाषिया के कार्यान्वयन को सरल बनाया (जो बोल्स को स्टैक पर 4 बाइट्स के रूप में मानता है) और कम से कम प्रतिरोध का मार्ग था। जब हमने iSeries "क्लासिक" जेवीएम को लागू किया, तो हमने उदाहरण के लिए 1 बाइट बनाने के तरीके ढूंढे, क्योंकि इससे कुछ वस्तुओं की कॉम्पैक्टीनेस में सुधार हुआ (जिसका प्रदर्शन पर आश्चर्यजनक प्रभाव पड़ा)। नीचे दिए गए पदों के आधार पर, सन / ओरेकल डेवलपर्स को यह पता लगा कि बाद के संस्करणों में इसी तरह कैसे करना है।
हॉट लिप्स

लेकिन यह सही है, 2017 के अंत तक जावाडॉक्स का कहना है: boolean: The boolean data type... This data type represents one bit of information, but its "size" isn't something that's precisely defined- लेकिन आपकी बात वैध है, यह कुछ लिंक और बेहतर जानकारी का उपयोग कर सकता है :)
JimLohse

185

यह वर्चुअल मशीन पर निर्भर करता है, लेकिन जावा में बाइट्स के बारे में पूछने वाले एक समान प्रश्न से कोड को अनुकूलित करना आसान है :

class LotsOfBooleans
{
    boolean a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    boolean c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    boolean d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    boolean e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}

class LotsOfInts
{
    int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}


public class Test
{
    private static final int SIZE = 1000000;

    public static void main(String[] args) throws Exception
    {        
        LotsOfBooleans[] first = new LotsOfBooleans[SIZE];
        LotsOfInts[] second = new LotsOfInts[SIZE];

        System.gc();
        long startMem = getMemory();

        for (int i=0; i < SIZE; i++)
        {
            first[i] = new LotsOfBooleans();
        }

        System.gc();
        long endMem = getMemory();

        System.out.println ("Size for LotsOfBooleans: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        System.gc();
        startMem = getMemory();
        for (int i=0; i < SIZE; i++)
        {
            second[i] = new LotsOfInts();
        }
        System.gc();
        endMem = getMemory();

        System.out.println ("Size for LotsOfInts: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        // Make sure nothing gets collected
        long total = 0;
        for (int i=0; i < SIZE; i++)
        {
            total += (first[i].a0 ? 1 : 0) + second[i].a0;
        }
        System.out.println(total);
    }

    private static long getMemory()
    {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
}

दोहराने के लिए, यह वीएम-निर्भर है, लेकिन सन के JDK बिल्ड 1.6.0_11 पर चलने वाले मेरे विंडोज लैपटॉप पर मुझे निम्नलिखित परिणाम मिले:

Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.0

इससे पता चलता है कि बूलियन मूल रूप से सन जेवीएम द्वारा प्रत्येक बाइट में पैक किया जा सकता है।


21
@ साकेत - मैं वास्तव में आपको सलाम करता हूं। आपका जवाब बहुत बढ़िया है
योद्धा

2
@warrior: जैसा कि मैंने पहले ही "बाइट" के लिए कोड प्राप्त कर लिया है, इसे "बूलियन" में बदलना बहुत सीधा था :)
जॉन स्कीट

3
System.gc () सफाई मेमोरी की गारंटी नहीं देता है। यह सिर्फ कचरा संग्रहण को चलाने के लिए जेवीएम को एक आदेश देता है, लेकिन इसका मतलब यह नहीं है कि कलेक्टर ने वास्तव में कुछ साफ किया है। याद रखें कलेक्टर असूचीबद्ध वस्तुओं को साफ करता है। एक ऑब्जेक्ट अप्रयुक्त है यदि प्रोग्राम इसके लिए अधिक संदर्भ नहीं रखता है। इसलिए आपके परीक्षण में मैं स्पष्ट रूप से ltsOfBooleans को gc () चलाने से पहले शून्य करने के लिए संदर्भ को छोड़ दूंगा; या बस एक बार बूलियन के साथ मुख्य चलाएं, एक बार इंट के साथ फिर संख्याओं की तुलना करें।
रंधा सेबी

2
@ रैंडसिटी या इससे भी बेहतर: सुनिश्चित करें कि आप दोनों संदर्भों को संरक्षित करते हैं और स्मृति अंतर की गणना करते हैं। जो वास्तव में यहाँ होता है।
biziclop

1
क्या कोई सवाल है जोन स्कीट जवाब नहीं दे सकता है?
एंड्रियास हार्टमैन

31

जावा में बूलियन मान द्वारा दर्शाई गई वास्तविक जानकारी एक बिट: 1 सच के लिए, 0 झूठी के लिए है। हालाँकि, मेमोरी में बूलियन चर का वास्तविक आकार जावा विनिर्देश द्वारा ठीक से परिभाषित नहीं किया गया है। जावा में आदिम डेटा प्रकार देखें ।

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


21

एक और बात...

यदि आप बूलियन वस्तुओं की एक सरणी का उपयोग करने के बारे में सोच रहे हैं, तो नहीं। इसके बजाय एक BitSet का उपयोग करें - इसमें कुछ प्रदर्शन अनुकूलन (और कुछ अच्छे अतिरिक्त तरीके हैं, जिससे आप अगला सेट / परेशान) प्राप्त कर सकते हैं।


यह हमेशा सही stackoverflow.com/questions/605226/…
Przemek

उस उत्तर से पता चलता है कि बूलियन [] का उपयोग करने के महत्वपूर्ण कारण हैं, लेकिन जैसा कि वहाँ संकेत मिलता है, इसे वापस करने के लिए बहुत कुछ नहीं है। बाद में कहा कि: मैं जावा में ज्यादा प्रोग्राम नहीं करता हूं (और या तो कोई सबूत नहीं दिया है?)
मैथ्यू Schinckel

6

मैंने पढ़ा कि जावा एक booleanडेटाटाइप के लिए एक बाइट रखता है , लेकिन यह केवल एक बिट का उपयोग करता है। हालाँकि, प्रलेखन का कहना है कि "इसका" आकार "कुछ ऐसा नहीं है जिसे ठीक से परिभाषित किया गया हो" यहाँ देखें।


यह एक ट्यूटोरियल है, 'प्रलेखन' नहीं। प्रलेखन JLS, JVM कल्पना, और Javadoc है।
लोर्ने के

2

booleanमूल्यों के लिए संकलित किया गया है intJVM में डेटा प्रकार। देखें यहाँ


2
यह जरूरी नहीं है कि उन्हें स्मृति में कैसे संग्रहीत किया जाता है, और मुझे लगता है कि वह वही है जो सवाल पूछने वाला व्यक्ति जानना चाहता था। वह दस्तावेज़ क्लास फ़ाइल प्रारूप (संकलित बाइट कोड) का वर्णन करता है, न कि मेमोरी में बूलियन चर का प्रतिनिधित्व, क्योंकि यह कार्यान्वयन-निर्भर है।
विलियम ब्रेंडल

2

जावा में बूलियन का आकार वर्चुअल मशीन पर निर्भर है। लेकिन किसी भी जावा ऑब्जेक्ट को 8 बाइट्स ग्रैन्युलैरिटी से जोड़ा जाता है। जानकारी के कुल 9 बाइट्स के लिए एक बूलियन में हेडर के 8 बाइट्स, और पेलोड के 1 बाइट होते हैं। तब JVM इसे 8. की अगली बहु तक गोल कर देता है। इसलिए java.lang.Boolean का एक उदाहरण मेमोरी के 16 बाइट्स लेता है।


मैं असहमत हूं, हॉटस्पॉट JVM 1.7.0_51 पर शीर्ष लेख में 12 बाइट्स + 1 है बूलियन के लिए + 3 ग्रैन्युलैरिटी के लिए।
यूजीन

14
बूलियन को बूलियन के साथ भ्रमित न करें।
andresp

1
बाइट्स या बिट्स? एक बाइट के लिए 16 बाइट्स एक Booleanऐसी बर्बादी है ... जिसका आकार longट्रिलियन गुणा से अधिक जानकारी ले सकता हैBoolean
डिसी

0

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

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