जावास्क्रिप्ट ऑब्जेक्ट का आकार कैसे प्राप्त करें?


296

मैं एक जावास्क्रिप्ट ऑब्जेक्ट द्वारा कब्जा किए गए आकार को जानना चाहता हूं।

निम्नलिखित कार्य करें:

function Marks(){
  this.maxMarks = 100;
}

function Student(){
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

अब मैं तुरंत student:

var stud = new Student();

ताकि मैं सामान जैसे कर सकूं

stud.firstName = "new Firstname";

alert(stud.firstName);

stud.marks.maxMarks = 200;

आदि।

अब, studमेमोरी में ऑब्जेक्ट कुछ आकार पर कब्जा कर लेगा। इसमें कुछ डेटा और अधिक ऑब्जेक्ट हैं।

मुझे कैसे पता चलेगा कि studऑब्जेक्ट कितनी मेमोरी में रहता है? sizeof()जावास्क्रिप्ट में कुछ ? यह वास्तव में भयानक होगा अगर मैं इसे एक ही फ़ंक्शन कॉल में पा सकता हूं जैसे sizeof(stud)

मैं महीनों से इंटरनेट पर खोज कर रहा हूं - यह नहीं मिल सका (एक-दो मंचों में पूछा गया - कोई जवाब नहीं)।


41
जावास्क्रिप्ट में किसी वस्तु का आकार खोजने के लिए बहुत सारे कारण हैं (उत्पन्न होंगे)। मैं जावास्क्रिप्ट के लिए नया हूं इसलिए मैं सर्वोत्तम प्रथाओं का पालन नहीं करता हूं। मैं अभी भी उन्हें सीख रहा हूं। मैंने एक फ़ायरफ़ॉक्स एक्सटेंशन विकसित किया है जो मुझे यकीन है कि इससे अधिक मेमोरी का उपयोग करना चाहिए। मैं कुछ तरीकों पर काम कर रहा हूं (उम्मीद है) मेमोरी का उपयोग कम करें .. प्रति टैब कई वस्तुओं के हजारों उदाहरणों के बारे में बात कर रहा हूं, इसलिए स्मृति कोई फर्क नहीं पड़ता है! बात यह है, मैं जानना चाहता हूं कि क्या वास्तव में मेरी स्मृति में कमी के प्रयास स्मृति को कम करने में मदद करते हैं .. और कितना।

1
यदि आपने एक FF एक्सटेंशन का निर्माण किया है, तो मैं आपको JS से उच्चतर भाषा स्तर पर जांच करने की सलाह दूंगा - देखिए कि FF पर क्या प्रभाव पड़ता है।
annakata

2
जेएस की तुलना में उच्च स्तरीय भाषा? इस मामले में क्या होगा?

24
यह आकार नहीं है जो वैसे भी मायने रखता है। यह है कि आप इसका उपयोग कैसे करते हैं। पुनश्च: क्या एक स्टड है!
थॉमस ईडिंग

13
@SpencerRuport ऑब्जेक्ट का आकार जानने का एक कारण एचटीएमएल 5 ऑफ़लाइन सक्षम अनुप्रयोगों के लिए होगा जहां आपके पास कभी-कभी सीमित स्थान होता है (5-10Mb को डेटा गहन अनुप्रयोग के लिए जल्दी से खाया जा सकता है)।
डेविड

जवाबों:


181

मैंने अपने मूल उत्तर में कोड को फिर से अंकित किया है । मैंने पुनरावृत्ति को हटा दिया है और मान लिया गया अस्तित्व उपरि हटा दिया है।

function roughSizeOfObject( object ) {

    var objectList = [];
    var stack = [ object ];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList.push( value );

            for( var i in value ) {
                stack.push( value[ i ] );
            }
        }
    }
    return bytes;
}

35
आप चाहें तो ऑब्जेक्ट कीज़ के बारे में भी सोच सकते हैं
zupa

8
जो कोई भी झूठे / सच्चे के उद्देश्यों के लिए सबसे छोटे प्रकार की तलाश में यहां उतरा है, वह अपरिभाषित / अशक्त प्रतीत होता है।
zupa

3
"よんもじ".lengthजावास्क्रिप्ट में 4 है, लेकिन क्या आपको यकीन है कि यह 8 बाइट्स है, क्योंकि आपका कोड इसे वापस करता है?
syockit

8
हां। जावास्क्रिप्ट में वर्ण ECMA-262 तृतीय संस्करण विशिष्टता के अनुसार संग्रहीत किए जाते हैं - bclary.com/2004/11/07/#a-4.3.16
-

4
यह फ़ंक्शन क्लोजर में छिपे संदर्भों की गणना नहीं करता है। उदाहरण के लिए var a={n:1}; var b={a:function(){return a}}; roughSizeOfObject(b)- यहां bसंदर्भ दिया गया है a, लेकिन roughSizeOfObject()रिटर्न 0
रोमन पोनोमोव

116

Google Chrome हीप प्रोइलर आपको ऑब्जेक्ट मेमोरी उपयोग का निरीक्षण करने की अनुमति देता है।

आपको ट्रेस में ऑब्जेक्ट का पता लगाने में सक्षम होने की आवश्यकता है जो मुश्किल हो सकता है। यदि आप विंडो वैश्विक पर ऑब्जेक्ट को पिन करते हैं, तो "कंटेनर" लिस्टिंग मोड से इसे ढूंढना बहुत आसान है।

संलग्न स्क्रीनशॉट में, मैंने विंडो पर "testObj" नामक एक ऑब्जेक्ट बनाया। मैं फिर प्रोफाइलर में स्थित (एक रिकॉर्डिंग बनाने के बाद) और यह ऑब्जेक्ट के पूर्ण आकार और उसमें "सब कुछ" बनाए हुए आकार के तहत दिखाता है।

मेमोरी टूटने पर अधिक जानकारी

क्रोम प्रोफाइलर

उपरोक्त स्क्रीनशॉट में, ऑब्जेक्ट 60 के आकार को बनाए रखता है। मेरा मानना ​​है कि यहां यूनिट बाइट्स है।


13
इस उत्तर ने मेरी समस्या को हल कर दिया: Developers.google.com/chrome-developer-tools/docs/… । त्वरित टिप: एक त्वरित हीप स्नैपशॉट लें, जिस कार्य पर आपको संदेह है उसे चलाएं, एक नया त्वरित हीप स्नैपशॉट लें और comparisonसबसे नीचे का दृश्य चुनें । यह स्पष्ट करता है कि दो स्नैपशॉट के बीच क्या ऑब्जेक्ट बनाए गए थे।
जॉनराइड

1
यह शायद सबसे साफ उपाय है।
लुका स्टीब

@ जॉनहाइड द्वारा उल्लिखित तुलना, अब शीर्ष पर एक पुलडाउन मेनू है।
फ्रैंड्रॉइड

Shallow sizeदोनों { a:"55c2067aee27593c03b7acbe", b:"55c2067aee27593c03b7acbe", c:null, d:undefined }और { c:null, d:undefined }वस्तुओं के लिए 40 के रूप में लगता है । ठीक है न?
एफफेकन

1
आप Google Chrome हीप प्रोइलर का उपयोग नोड से भी कर सकते हैं। यदि आपके पास नोड v8 है या इससे ऊपर है node --inspectऔर क्रोम about:inspectमें URL बार में दर्ज करें और नोड इंस्पेक्टर को खोलने के लिए देखें। नोड सीएलआई में अपनी वस्तु बनाएं और फिर एक ढेर स्नैपशॉट लें।
ग्रेगोर

74

मैंने ऐसा ही (ish) समस्या हल करने के लिए लिखा था। यह बिल्कुल वैसा नहीं है जैसा आप देख रहे हैं, यानी यह इस बात पर ध्यान नहीं देता है कि दुभाषिया वस्तु को कैसे संग्रहीत करता है।

लेकिन, यदि आप V8 का उपयोग कर रहे हैं, तो यह आपको एक बहुत ही बढ़िया सन्निकटन प्रदान करना चाहिए क्योंकि भयानक प्रोटोटाइप और छिपी हुई कक्षाएं अधिकांश ओवरहेड को चाटती हैं।

function roughSizeOfObject( object ) {

    var objectList = [];

    var recurse = function( value )
    {
        var bytes = 0;

        if ( typeof value === 'boolean' ) {
            bytes = 4;
        }
        else if ( typeof value === 'string' ) {
            bytes = value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes = 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf( value ) === -1
        )
        {
            objectList[ objectList.length ] = value;

            for( i in value ) {
                bytes+= 8; // an assumed existence overhead
                bytes+= recurse( value[i] )
            }
        }

        return bytes;
    }

    return recurse( object );
}

1
@Liangliang Zheng - महान बिंदु फिर से अनंत लूप, धन्यवाद। आशा है कि आप बुरा नहीं मानेंगे अगर मैं इसे थोड़ा सा गिग करूं और काम के बाद मेरा (?)
थोमस-पीटर

मैं आज रात नोड.जेएस के साथ इस बेंच का परीक्षण करने जा रहा हूं और कुछ बेहतर गुणांक प्राप्त कर रहा हूं।
थोमस-पीटर

'बाइट्स + = रिकर्स (वैल्यू [i])' लाइन, मेरे FF 14.01 में त्रुटि फेंकता है: NS_ERROR_FAILURE: घटक ने विफलता कोड दिया: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMHTMLInputElement.selectionStart]। मेरी एक वस्तु पर, अगर मैं एक अलग कोशिश करता हूं, तो यह नहीं होता है, शायद एक ब्राउज़र बग, या कोड हर वस्तु के लिए काम नहीं करता है (जो काम नहीं करता है उसमें फ़ंक्शन शामिल हैं, जो काम नहीं करता है ' t)
ट्रायस्पेस

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

4
यह PHP (gulp) है जिसे मुझे देखना है - मैंने उसे बहुत समय पहले प्यार करना बंद कर दिया था लेकिन वह बिलों का भुगतान करती है। वैसे भी, धन्यवाद टॉम, प्रतिक्रिया कि तरह प्रतिष्ठा अंक से बेहतर है।
थॉमस-पीटर

55

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

यह भी ध्यान दें, यह धीमा है, केवल देव। लेकिन कोड की एक पंक्ति के साथ बॉलपार्क उत्तर पाने के लिए यह मेरे लिए उपयोगी है।

roughObjSize = JSON.stringify(bigObject).length;

2
मेरे परीक्षणों से, यह विधि ऑब्जेक्ट-आकार के मामले की तुलना में काफी तेज है क्योंकि इसमें धीमी गति से _.isObject () कॉल नहीं है। इसके अलावा लौटे आकार मोटे अनुमान के लिए काफी तुलनीय हैं। सार gist.github.com/owenallenaz/ff77fc98081708146495
न्यूक्लियर सिप


5
परिपत्र संरचनाओं के साथ उपयोग नहीं कर सकते VM1409:1 Uncaught TypeError: Converting circular structure to JSON:( अभी भी उपयोगी हालांकि
givanse

यह बाइट्स में द्विआधारी आकार नहीं है, लेकिन अनुमानित आकार प्राप्त करने के लिए उपयोग करने के लिए सरल है
datdinhquoc

यह बहुत अच्छा है अगर 1) आपको केवल एक बॉलपार्क अनुमान 2 की आवश्यकता है) आपको पता है कि आपके पास कोई परिपत्र संदर्भ नहीं है 3) आप बड़े मूल्यों को छोड़ सकते हैं और उन्हें अलग से गड़बड़ कर सकते हैं। ये सभी मेरे मामले में सच थे इसलिए पूरी तरह से काम करता है, मेरे पास केवल एक ही जगह पर एक बड़ा स्ट्रिंग था जिसे मैं सिर्फ लंबाई माप सकता हूं।
OZZIE

43

यहाँ समस्या का थोड़ा और अधिक कॉम्पैक्ट समाधान है:

const typeSizes = {
  "undefined": () => 0,
  "boolean": () => 4,
  "number": () => 8,
  "string": item => 2 * item.length,
  "object": item => !item ? 0 : Object
    .keys(item)
    .reduce((total, key) => sizeOf(key) + sizeOf(item[key]) + total, 0)
};

const sizeOf = value => typeSizes[typeof value](value);

3
तो यह KB में आकार है? या बिट्स?
विन्सेन्ट थोरपे

2
@ विन-थोरपे यह बाइट्स में है।
दान

2
अच्छी पटकथा, हालांकि चक्रीय संदर्भों के लिए संशोधनों की आवश्यकता है।
जिम पेडिड

1
मैंने अभी-अभी नोड प्रक्रिया के भीतर डेटा के एक विशाल सरणी पर आपके एल्गोरिदम का परीक्षण किया है, यह 13GB रिपोर्ट करता है, लेकिन नोड 22GB का उपभोग कर रहा है, किसी भी विचार के बारे में कि अंतर कहां से आता है? स्मृति में अधिक कुछ नहीं है।
जोसु गोनी

3
@ JosuGoñi, वे इस बात की गणना नहीं करते हैं कि वस्तु स्वयं कितना मूल्य लेती है, केवल उसका मूल्य। सभी वस्तुएं केवल अपने मूल्य से अधिक स्थान लेती हैं, अन्यथा typeof ...काम नहीं करती।
एलेक्सिस विलके

42

ऑब्जेक्ट साइमॉफ प्राप्त करने के लिए एक एनपीएम मॉड्यूल है , आप इसे स्थापित कर सकते हैंnpm install object-sizeof

  var sizeof = require('object-sizeof');

  // 2B per character, 6 chars total => 12B
  console.log(sizeof({abc: 'def'}));

  // 8B for Number => 8B
  console.log(sizeof(12345));

  var param = { 
    'a': 1, 
    'b': 2, 
    'c': {
      'd': 4
    }
  };
  // 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
  console.log(sizeof(param));

sizeof (नई तिथि ()) === 0 और sizeof ({}) === 0. क्या इसका उद्देश्य है?
फिलिप क्लेन

1
@ PhilippClaßen स्पष्ट रूप से यह है। दोनों वस्तुओं में कोई गुण नहीं है।
राबर्ट

18

यह एक हैक करने की विधि है, लेकिन मैंने इसे दो बार अलग-अलग संख्याओं के साथ आज़माया और यह सुसंगत प्रतीत होता है।

आप जो कुछ भी कर सकते हैं वह कोशिश करना है और बड़ी संख्या में वस्तुओं को आवंटित करना है , जैसे कि आप चाहते हैं कि एक या दो मिलियन ऑब्जेक्ट। कचरे को इकट्ठा करने वाले को छोड़ने से रोकने के लिए ऑब्जेक्ट को एक सरणी में रखें (ध्यान दें कि यह सरणी के कारण थोड़ी मेमोरी ओवरहेड जोड़ देगा, लेकिन मुझे आशा है कि यह कोई फर्क नहीं पड़ना चाहिए और इसके अलावा अगर आप वस्तुओं को स्मृति में होने के बारे में चिंता करने जा रहे हैं। , आप उन्हें कहीं स्टोर करें)। आवंटन से पहले और बाद में एक अलर्ट जोड़ें और प्रत्येक अलर्ट में देखें कि फ़ायरफ़ॉक्स प्रक्रिया कितनी मेमोरी ले रही है। इससे पहले कि आप पृष्ठ को परीक्षण के साथ खोलें, सुनिश्चित करें कि आपके पास एक नया फ़ायरफ़ॉक्स उदाहरण है। पृष्ठ खोलें, "पहले" अलर्ट दिखाए जाने के बाद मेमोरी उपयोग पर ध्यान दें। अलर्ट बंद करें, मेमोरी आवंटित होने की प्रतीक्षा करें। पुरानी से नई मेमोरी को घटाएं और आवंटन की मात्रा से विभाजित करें।

function Marks()
{
  this.maxMarks = 100;
}

function Student()
{
  this.firstName = "firstName";
  this.lastName = "lastName";
  this.marks = new Marks();
}

var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
    manyObjects[i] = new Student();
alert('after');

मैंने अपने कंप्यूटर में यह कोशिश की और इस प्रक्रिया में 48352K मेमोरी थी जब "पहले" अलर्ट दिखाया गया था। आवंटन के बाद, फ़ायरफ़ॉक्स में 440236K मेमोरी थी। 2million आवंटन के लिए, यह प्रत्येक ऑब्जेक्ट के लिए लगभग 200 बाइट्स है।

मैंने इसे 1 मिलियन आवंटन के साथ फिर से कोशिश की और परिणाम समान था: प्रति ऑब्जेक्ट 196 बाइट्स (मुझे लगता है कि 2मिल में अतिरिक्त डेटा का उपयोग ऐरे के लिए किया गया था)।

तो, यहाँ एक हैकी विधि है जो आपकी मदद कर सकती है। जावास्क्रिप्ट एक कारण के लिए "आकार" विधि प्रदान नहीं करता है: प्रत्येक जावास्क्रिप्ट कार्यान्वयन अलग है। उदाहरण के लिए Google Chrome में प्रत्येक वस्तु के लिए एक ही पृष्ठ लगभग 66 बाइट्स का उपयोग करता है (कार्य प्रबंधक से कम से कम देखकर)।


अरे .. तकनीक के लिए धन्यवाद। मैं कर रहा था कि योजना बी के रूप में स्मृति के उपयोग को मापने के लिए कोई सीधा रास्ता नहीं था।

4
प्रत्येक C और C ++ कार्यान्वयन भी अलग है। ;) C या C ++ में डेटा प्रकार का आकार कार्यान्वयन विशिष्ट है। मुझे लगता है कि कोई कारण नहीं है कि जावास्क्रिप्ट इस तरह के एक ऑपरेटर का समर्थन नहीं कर सकता है, हालांकि यह एक ही उद्देश्य की सेवा नहीं करेगा या इसका वही अर्थ होगा जो सी या सी ++ में होता है (जो निचले स्तर की भाषाएं हैं और एक निश्चित आकार का वास्तविक माप करते हैं- आकार डेटा प्रकार संकलित समय पर रन-टाइम में एक गतिशील जावास्क्रिप्ट ऑब्जेक्ट के चर-आकार के विपरीत)।
बंबाम्स

12

क्षमा करें, मैं टिप्पणी नहीं कर सकता, इसलिए मैं सिर्फ टॉमरॉन्ग से काम जारी रखता हूं। यह वर्धित संस्करण एक से अधिक बार ऑब्जेक्ट की गणना नहीं करेगा, इस प्रकार कोई अनंत लूप नहीं होगा। इसके अलावा, मुझे लगता है कि एक वस्तु की कुंजी को भी गिना जाना चाहिए, मोटे तौर पर।

function roughSizeOfObject( value, level ) {
    if(level == undefined) level = 0;
    var bytes = 0;

    if ( typeof value === 'boolean' ) {
        bytes = 4;
    }
    else if ( typeof value === 'string' ) {
        bytes = value.length * 2;
    }
    else if ( typeof value === 'number' ) {
        bytes = 8;
    }
    else if ( typeof value === 'object' ) {
        if(value['__visited__']) return 0;
        value['__visited__'] = 1;
        for( i in value ) {
            bytes += i.length * 2;
            bytes+= 8; // an assumed existence overhead
            bytes+= roughSizeOfObject( value[i], 1 )
        }
    }

    if(level == 0){
        clear__visited__(value);
    }
    return bytes;
}

function clear__visited__(value){
    if(typeof value == 'object'){
        delete value['__visited__'];
        for(var i in value){
            clear__visited__(value[i]);
        }
    }
}

roughSizeOfObject(a);

मुझे लगता है कि यह गिनती की कुंजी के रूप में अधिक सटीक है, हालांकि यह '__visited__' कुंजी की गिनती करता है
सैम

जाँच करना typeof value === 'object'पर्याप्त नहीं है और यदि मूल्य है तो आपके पास अपवाद होंगे null
फ्लोरिनॉन

यह किसी भी @ टोमरॉन्ग के दुस्साहसी उत्तरों की तुलना में मेरी वस्तु के लिए तेजी से धधक रहा था (जिस पर मुझे पूरा विश्वास है कि यह 5mb से अधिक का रास्ता है)। यह भी अधिक सटीक था (जैसा कि 3mb या ऐसा कहा गया है) लेकिन फिर भी वास्तविकता से बहुत दूर है। क्या यह गिनती नहीं हो सकता है पर कोई सुराग?
Cregox

मेरे लिए काम नहीं करता है। ऑब्जेक्ट levelमें डेटा होता है लेकिन roughSizeOfObject(level)शून्य होता है। (मेरा चर स्तर आपके तर्क से भ्रमित होने वाला नहीं है, निश्चित रूप से। मुझे नहीं लगता कि परिवर्तनशील छायांकन यहाँ एक समस्या का कारण बन सकता है, और यह भी कि जब मैं आपकी स्क्रिप्ट में 'स्तर' का नाम बदलूँ तो मुझे वही परिणाम मिलता है।) स्क्रीनशॉट : snipboard.io/G7E5yj.jpg
ल्यूक

10

एक ही समस्या होने। मैंने Google पर खोज की है और मैं इस समाधान के लिए स्टैकओवरफ़्लो समुदाय के साथ साझा करना चाहता हूं।

महत्वपूर्ण :

मैंने यान किंग द्वारा गिथब https://gist.github.com/zensh/4975495 पर साझा किए गए फ़ंक्शन का उपयोग किया

function memorySizeOf(obj) {
    var bytes = 0;

    function sizeOf(obj) {
        if(obj !== null && obj !== undefined) {
            switch(typeof obj) {
            case 'number':
                bytes += 8;
                break;
            case 'string':
                bytes += obj.length * 2;
                break;
            case 'boolean':
                bytes += 4;
                break;
            case 'object':
                var objClass = Object.prototype.toString.call(obj).slice(8, -1);
                if(objClass === 'Object' || objClass === 'Array') {
                    for(var key in obj) {
                        if(!obj.hasOwnProperty(key)) continue;
                        sizeOf(obj[key]);
                    }
                } else bytes += obj.toString().length * 2;
                break;
            }
        }
        return bytes;
    };

    function formatByteSize(bytes) {
        if(bytes < 1024) return bytes + " bytes";
        else if(bytes < 1048576) return(bytes / 1024).toFixed(3) + " KiB";
        else if(bytes < 1073741824) return(bytes / 1048576).toFixed(3) + " MiB";
        else return(bytes / 1073741824).toFixed(3) + " GiB";
    };

    return formatByteSize(sizeOf(obj));
};


var sizeOfStudentObject = memorySizeOf({Student: {firstName: 'firstName', lastName: 'lastName', marks: 10}});
console.log(sizeOfStudentObject);

आपने इस बारे में क्या सोचा?


3
यह कार्य याद करता है। यदि मैं एक फ़ंक्शन जोड़ता हूं, तो ऑब्जेक्ट किसी भी बड़े रूप में नहीं दिखता है
डॉन रम्मी


7

मैं यह जानना चाहता हूं कि क्या वास्तव में मेरी स्मृति में कमी के प्रयास स्मृति को कम करने में मदद करते हैं

इस टिप्पणी के बाद, यहां आपको क्या करना चाहिए: मेमोरी समस्या उत्पन्न करने का प्रयास करें - कोड लिखें जो इन सभी वस्तुओं को बनाता है और जब तक आप समस्या में नहीं चले जाते हैं तब तक ऊपरी सीमा बढ़ाते हैं (ब्राउज़र क्रैश, ब्राउज़र फ्रीज़ या आउट-ऑफ- स्मृति त्रुटि)। आदर्श रूप से आपको विभिन्न ब्राउज़रों और अलग ऑपरेटिंग सिस्टम के साथ इस प्रयोग को दोहराना चाहिए।

अब दो विकल्प हैं: विकल्प 1 - आप मेमोरी समस्या के निर्माण में सफल नहीं हुए। इसलिए, आप कुछ नहीं के लिए चिंता कर रहे हैं। आपके पास स्मृति समस्या नहीं है और आपका कार्यक्रम ठीक है।

विकल्प 2- आपको मेमोरी प्रॉब्लम हुई। अब अपने आप से पूछें कि क्या समस्या जिस सीमा पर है वह उचित है (दूसरे शब्दों में: क्या यह संभावना है कि आपके कोड के सामान्य उपयोग में वस्तुओं की यह राशि बनाई जाएगी)। यदि उत्तर 'नहीं' है तो आप ठीक हैं। अन्यथा अब आप जानते हैं कि आपका कोड कितनी वस्तुएं बना सकता है। एल्गोरिथ्म को फिर से चलाएँ जैसे कि यह इस सीमा को भंग नहीं करता है।


मेमोरी स्टैंड बिंदु से, मेरा एक्सटेंशन फ़ायरफ़ॉक्स में खुले प्रत्येक पृष्ठ / टैब के लिए कई ऑब्जेक्ट जोड़ता है। "संख्या" पृष्ठ के आकार के लिए आनुपातिक है। यह मानते हुए कि "पावर" उपयोगकर्ताओं के पास 15 से 20 टैब खुले हैं, और यदि वेब पेज में बहुत अधिक सामग्री है, तो ब्राउज़र कुछ समय बाद धीमा और निराशाजनक रूप से गैर-उत्तरदायी हो जाता है। यह मेरे बिना भी स्पष्ट रूप से एप्लिकेशन को तनाव देने की कोशिश कर रहा है। मेरे पास कोड को फिर से लिखने की योजना है जो मुझे लगता है कि बहुत सारे ऑब्जेक्ट निर्माण को कम कर देगा। मैं बस यह सुनिश्चित करना चाहता था कि नहीं। वस्तुओं की मात्रा कुछ घट गई ताकि वह इसके लायक हो

@ सेंथिल: लेकिन ऑब्जेक्ट साइज़ का कोई मतलब नहीं है जब तक आप उपलब्ध मेमोरी की मात्रा नहीं जानते हैं। चूँकि स्मृति की मात्रा एक रहस्य बने रहने की संभावना है, इसलिए #objects के संदर्भ में बोलना उतना ही उपयोगी है, जितना कि #bytes
Itay Maman

5

यदि आपकी मुख्य चिंता आपके फ़ायरफ़ॉक्स एक्सटेंशन की मेमोरी उपयोग है, तो मैं मोज़िला डेवलपर्स के साथ जांच करने का सुझाव देता हूं।

मोज़िला अपने विकी पर स्मृति लीक का विश्लेषण करने के लिए उपकरणों की एक सूची प्रदान करता है ।


5

यह जावास्क्रिप्ट लाइब्रेरी sizeof.jsभी यही काम करती है। इसे इस तरह शामिल करें

<script type="text/javascript" src="sizeof.js"></script>

Sizeof फ़ंक्शन ऑब्जेक्ट को पैरामीटर के रूप में लेता है और बाइट्स में इसके अनुमानित आकार को वापस करता है। उदाहरण के लिए:

// define an object
var object =
    {
      'boolean' : true,
      'number'  : 1,
      'string'  : 'a',
      'array'   : [1, 2, 3]
    };

// determine the size of the object
var size = sizeof(object);

आकार का कार्य उन वस्तुओं को संभाल सकता है जिनमें अन्य वस्तुओं के कई संदर्भ होते हैं और पुनरावर्ती संदर्भ होते हैं।

मूल रूप से यहां प्रकाशित


यह धीमा है और मेरे उपयोग के मामले में @liangliang की तुलना में "कम सटीक" प्रतीत होता है।
cregox


2

इसके लिए कोड पर काम कर रहे सभी को बहुत धन्यवाद!

मैं बस यह जोड़ना चाहता था कि मैं ठीक उसी चीज की तलाश कर रहा हूं, लेकिन मेरे मामले में यह संसाधित वस्तुओं के कैश का प्रबंधन करने के लिए है जो कि अजाक्स कॉल से वस्तुओं को फिर से पार्स और संसाधित करने से बचने के लिए हो सकता है या कैश नहीं किया गया हो सकता है ब्राउज़र द्वारा। यह उन वस्तुओं के लिए विशेष रूप से उपयोगी है जिनके लिए बहुत अधिक प्रसंस्करण की आवश्यकता होती है, आमतौर पर कुछ भी जो JSON प्रारूप में नहीं है, लेकिन एक बड़ी परियोजना या ऐप / एक्सटेंशन में कैश्ड इन चीजों को रखने के लिए बहुत महंगा हो सकता है जो लंबे समय तक चलता रहता है। समय।

वैसे भी, मैं इसे कुछ के लिए उपयोग करता हूं जैसे:

var myCache = {
    cache: {},
    order: [],
    size: 0,
    maxSize: 2 * 1024 * 1024, // 2mb

    add: function(key, object) {
        // Otherwise add new object
        var size = this.getObjectSize(object);
        if (size > this.maxSize) return; // Can't store this object

        var total = this.size + size;

        // Check for existing entry, as replacing it will free up space
        if (typeof(this.cache[key]) !== 'undefined') {
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    total -= entry.size;
                    this.order.splice(i, 1);
                    break;
                }
            }
        }

        while (total > this.maxSize) {
            var entry = this.order.shift();
            delete this.cache[entry.key];
            total -= entry.size;
        }

        this.cache[key] = object;
        this.order.push({ size: size, key: key });
        this.size = total;
    },

    get: function(key) {
        var value = this.cache[key];
        if (typeof(value) !== 'undefined') { // Return this key for longer
            for (var i = 0; i < this.order.length; ++i) {
                var entry = this.order[i];
                if (entry.key === key) {
                    this.order.splice(i, 1);
                    this.order.push(entry);
                    break;
                }
            }
        }
        return value;
    },

    getObjectSize: function(object) {
        // Code from above estimating functions
    },
};

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


1
function sizeOf(parent_data, size)
{
    for (var prop in parent_data)
    {
        let value = parent_data[prop];

        if (typeof value === 'boolean')
        {
            size += 4;
        }
        else if (typeof value === 'string')
        {
            size += value.length * 2;
        }
        else if (typeof value === 'number')
        {
             size += 8;
        }
        else
        {      
            let oldSize = size;
            size += sizeOf(value, oldSize) - oldSize;
        }
    }

    return size;
}


function roughSizeOfObject(object)
{   
    let size = 0;
    for each (let prop in object)
    {    
        size += sizeOf(prop, 0);
    } // for..
    return size;
}

1

मैं क्रोम देव टूल्स ' टाइमलाइन टैब ' का उपयोग करता हूं , तेजी से बड़ी मात्रा में ऑब्जेक्ट्स को त्वरित करता है, और उस तरह के अच्छे अनुमान प्राप्त करता है। आप बॉयलरप्लेट के रूप में नीचे इस तरह से html का उपयोग कर सकते हैं, और अपनी वस्तुओं की विशेषताओं (संख्या और गुणों के प्रकार, आदि ...) को बेहतर ढंग से अनुकरण करने के लिए इसे संशोधित कर सकते हैं। आप पहले और बाद में, उस उपकरण के नीचे टैब पर ट्रैश बिट आइकन पर क्लिक करना चाह सकते हैं।

<html>
<script>
var size = 1000*100
window.onload = function() {
  document.getElementById("quantifier").value = size
}

function scaffold()
{
  console.log("processing Scaffold...");
  a = new Array
}

function start()
{
  size = document.getElementById("quantifier").value
  console.log("Starting... quantifier is " + size);
  console.log("starting test")
  for (i=0; i<size; i++){
    a[i]={"some" : "thing"}
  }
  console.log("done...")
}

function tearDown()
{
  console.log("processing teardown");
  a.length=0
}

</script>
<body>
    <span style="color:green;">Quantifier:</span>
    <input id="quantifier" style="color:green;" type="text"></input>
    <button onclick="scaffold()">Scaffold</button>
    <button onclick="start()">Start</button>
    <button onclick="tearDown()">Clean</button>
    <br/>
</body>
</html>

सिर्फ एक ही संपत्ति (जैसा कि ऊपर इस कोड में है) के 2 मिलियन ऑब्जेक्ट्स को इंस्टेंट करने से मेरे क्रोमियम पर, प्रति वस्तु 50 बाइट्स की लगभग गणना होती है। प्रति ऑब्जेक्ट एक यादृच्छिक स्ट्रिंग बनाने के लिए कोड को बदलना प्रति ऑब्जेक्ट में कुछ 30 बाइट्स जोड़ता है, आदि। आशा है कि यह मदद करता है।


1

यदि आपको aprox के लिए प्रोग्राम करने की आवश्यकता है। वस्तुओं का आकार आप इस लाइब्रेरी को भी देख सकते हैं। http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/ कि मैं वस्तुओं के आकार के लिए उपयोग करने के लिए सक्षम है।

अन्यथा मैं क्रोम / फ़ायरफ़ॉक्स हीप प्रोइलर का उपयोग करने का सुझाव देता हूं।


-3

मेरा मानना ​​है कि आप 'सरणी' को शामिल करना भूल गए।

  typeOf : function(value) {
        var s = typeof value;
        if (s === 'object')
        {
            if (value)
            {
                if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')) && typeof value.splice === 'function')
                {
                    s = 'array';
                }
            }
            else
            {
                s = 'null';
            }
        }
        return s;
    },

   estimateSizeOfObject: function(value, level)
    {
        if(undefined === level)
            level = 0;

        var bytes = 0;

        if ('boolean' === typeOf(value))
            bytes = 4;
        else if ('string' === typeOf(value))
            bytes = value.length * 2;
        else if ('number' === typeOf(value))
            bytes = 8;
        else if ('object' === typeOf(value) || 'array' === typeOf(value))
        {
            for(var i in value)
            {
                bytes += i.length * 2;
                bytes+= 8; // an assumed existence overhead
                bytes+= estimateSizeOfObject(value[i], 1)
            }
        }
        return bytes;
    },

   formatByteSize : function(bytes)
    {
        if (bytes < 1024)
            return bytes + " bytes";
        else
        {
            var floatNum = bytes/1024;
            return floatNum.toFixed(2) + " kb";
        }
    },

1
जेएस में, एक सरणी एक वस्तु है। कार्यान्वयन में कुछ अनुकूलन हो सकते हैं, लेकिन वैचारिक रूप से सरणियाँ और वस्तुएं समान हैं।
क्रिस वॉकर

-8

मुझे पता है यह ऐसा करने का बिल्कुल सही तरीका नहीं है, फिर भी इसने मुझे लगभग कुछ समय पहले मदद की है कि लगभग अनुमानित फाइल को प्राप्त करें:

कंसोल या नए टैब पर अपनी वस्तु / प्रतिक्रिया लिखें, परिणामों को एक नई नोटपैड फ़ाइल में कॉपी करें, इसे सहेजें, और फ़ाइल का आकार जांचें। नोटपैड फ़ाइल अपने आप में केवल कुछ बाइट्स है, इसलिए आपको एक बिल्कुल सटीक ऑब्जेक्ट फ़ाइल आकार मिलेगा।


4
यह पूरी तरह से गलत है। उदाहरण के लिए संख्या 1/3 = 0.3333333333333333 पर विचार करें। यह आपके दृष्टिकोण का उपयोग करके 18 बाइट्स होगा।
कोरियाजिस

2
मैंने कहा कि यह अनुमानित था । कभी-कभी आप परवाह नहीं करते हैं यदि यह 1MB या 1.00001MB है, तो आप केवल एक अनुमान जानना चाहते हैं, तो यह विधि पूरी तरह से ठीक है।
जेफरी रोसडेन्गल

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