2011-06-01 14 views
15

कभी-कभी मैं MATLAB स्क्रिप्ट शुरू करता हूं और बहुत देर से महसूस करता हूं कि यह बहुत अधिक आंकड़ों को आउटपुट करने जा रहा है। आखिरकार मैं एकबहुत सारे आंकड़े खोलते समय MATLAB क्रैश से कैसे बचें?

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

जो आसानी से मेरी मशीन का उपयोग कर पर पुनः प्रस्तुत किया जा सकता है

for i=1:inf 
    figure; 
end 

मैं करने के लिए मिल के आसपास 90 आंकड़े से पहले ही 128 एमबी जावा ढेर के मानक सेटिंग (Preferences/Java Heap Memory) के साथ दुर्घटनाओं, जबकि ढेर को दोगुना करने के लिए 256 एमबी मुझे लगभग 200 आंकड़े देता है।

क्या आप पर कोई भी तरीका देखते हैं जावा त्रुटि संदेश से बचें? यदि किसी अन्य आकृति के लिए पर्याप्त स्मृति नहीं है, तो मैं अपनी स्क्रिप्ट को को को दुर्घटना के बजाय बताया था।

शायद मुझे figure के लिए एक रैपर हो सकता है जो (किसी भी तरह?) जांचता है कि जावा ढेर कितना उपलब्ध है और यदि पर्याप्त जगह नहीं है तो कोई नया आंकड़ा खोलने से इंकार कर देता है? का उपयोग कर

for i=1:inf 
    java.lang.Runtime.getRuntime.gc 
    fprintf('%3.0f: %1.0f Byte free\n',i,java.lang.Runtime.getRuntime.freeMemory); 
    figure; 
end 

मैं

figure;plot(freeMem/1E6,'x');ylabel('java.lang.Runtime.getRuntime.freeMemory [MB]');xlabel('number of empty figures created');

यह उत्पादन किया गया था:

अद्यतन

नीचे दिए गए उत्तर का उपयोग करना, मैं कितना मुक्त मेमोरी जावा है के लिए एक अच्छी ग्राफ मिल मान लें कि शुरुआत में वृद्धि का मतलब है कि कचरा संग्रह केवल एक निश्चित प्रयास करता है बहुत समय मैं इसे बुलाता हूँ?

अद्यतन 2 - मेरी समाधान

मदद मैं यहाँ मिल गया का उपयोग करना, मैं एक figure.m जो overloads और कॉल के रूप में निम्नलिखित समाधान लागू निर्माण में figure आदेश:

function varargout=figure(varargin) 
memcutoff = 10E6; % keep at least this amount of bytes free 
memkeyboard= 3E6; % if memory drops below this, interrupt execution and go to keyboard mode 
global refuse_new_figures 
if refuse_new_figures 
    warning('jb:fig:lowjavamem2','Java WAS memory low -> refusing to create a new figure. To reset, type "global refuse_new_figures ; refuse_new_figures = [];"'); 
    return 
end 
freemem=java.lang.Runtime.getRuntime.freeMemory; 
if freemem < memcutoff 
    fprintf('Free memory is low (%1.0f Bytes) -> running garbace collector...\n',freemem); 
    java.lang.Runtime.getRuntime.gc 
end 
freemem=java.lang.Runtime.getRuntime.freeMemory; 
% fprintf('Free memory is %1.0f Bytes.\n',freemem); 
if freemem < memkeyboard 
    warning('jb:fig:lowjavamem','Java memory very low -> going into interactive mode. Good luck!'); 
    keyboard; 
end 
if freemem < memcutoff 
    warning('jb:fig:lowjavamem','Java memory low -> refusing to create a new figure!'); 
    refuse_new_figures=true; 
else 
    if nargin > 0 
     if nargout > 0 
      varargout{1}=builtin('figure',varargin{:}); 
     else 
      builtin('figure',varargin{:}); 
     end 
    else 
     if nargout > 0 
      varargout{1}=builtin('figure'); 
     else 
      builtin('figure'); 
     end 
    end 
end 
+0

अच्छा अद्यतन। अगर मैं कर सकता तो मैं इसे दूसरी बार वोट दूंगा। मुझे आश्चर्य है कि जावा की वजह से वृद्धि अधिक स्मृति आवंटित हो सकती है। – Jonas

उत्तर

6

सामान्य में , मैं अधिकतम जावा हीप मेमोरी को उपलब्ध रैम के लगभग 25% तक सेट करने का सुझाव दूंगा, जो आपको कई आंकड़े खोलने की अनुमति देता है (लेकिन असीमित संख्या नहीं)। यदि आप वरीयताओं में ऐसा नहीं कर सकते हैं (उदा। बी/सी आपके पास मैक जैसा है), this solution मदद करेगा - यह वरीयता सेटिंग्स को ओवरराइड करता है।

जुड़ा हुआ समाधान भी आपको बताता है कि कितना मुक्त जावा स्मृति को छोड़ दिया है, और कितना कुल उपलब्ध है: निम्न कमांड चलाएँ:

java.lang.Runtime.getRuntime.maxMemory 
java.lang.Runtime.getRuntime.totalMemory 
java.lang.Runtime.getRuntime.freeMemory 

दुर्भाग्य से, एक आंकड़ा की एक निश्चित राशि नहीं ले करता है जावा मेमोरी, एक खाली आंकड़ा 10k अंकों को प्रदर्शित करने से बहुत कम लेता है, और एक न्यूनतम आंकड़े अधिकतम से कम स्मृति लेता है। हालांकि, यदि आप प्रति आकृति की औसत स्मृति की अनुमान लगा सकते हैं, तो आप वास्तव में figure के लिए एक रैपर लिख सकते हैं जो जांचता है कि यह आंकड़ा आखिरी होगा। वैकल्पिक रूप से/इसके अतिरिक्त, आप रैपर फ़ंक्शन को अन्य सभी आंकड़ों को कम कर सकते हैं (see Undocumented Matlab इसके लिए)।

संपादित रूप @Peter Lawrey से कहा, आप भी कोशिश करते हैं और जाँच कितनी स्मृति उपलब्ध है इससे पहले कि कचरा संग्रहण प्रदर्शन कर सकते हैं - हालांकि मैं नहीं पता कि मैटलैब कि वैसे भी कोशिश करेगा,।

+3

freeMemory केवल आपको बताता है कि कितना अब नि: शुल्क है, यदि आप एक जीसी प्रदर्शन नहीं कितना मुक्त हो जाएगी। –

2

आप मुक्त स्मृति जाँच कर सकते हैं, अगर वहाँ कोई पर्याप्त ट्रिगर एक जीसी है और फिर से जाँच करें। यदि अभी भी पर्याप्त नहीं है, तो असफल हो जाएं। आप 1-10 एमबी हेड रूम की अनुमति दे सकते हैं।

आप Runtime.gc() और Runtime.freeMemory() का उपयोग कर सकते हैं;

आप अधिकतम स्मृति सेट नहीं करते हैं यह यह उपलब्ध स्मृति का एक प्रतिशत कर देगा।

+2

एक जेवीएम आउटऑफमेमरी त्रुटि फेंकने से पहले जीसी स्वचालित रूप से स्वचालित रूप से घटित होगा, इसलिए अंतरिक्ष को मुक्त करने के लिए 'Runtime.gc()' को एक स्पष्ट कॉल वास्तव में आवश्यक नहीं है, लेकिन निश्चित रूप से उपयोग करने योग्य मेमोरी के लिए मूलभूत आंकड़े प्राप्त करने में मदद करता है। याद रखने की एक बात यह है कि वीएम निर्णय लेता है कि जीसी कब, 'Runtime.gc() 'कॉल हर मामले में कचरा संग्रह नहीं होता है। – BertNase

+0

मैटलैब प्रोग्राम के लिए अधिकतम जावा मेमोरी सेट करेगा, जो कोई भी कर सकता है यह चुनना है कि यह कितना होना चाहिए। – Jonas

1

मैं अपने खुद के समारोह 'limfig' है, जहां imglimit आंकड़े आप चाहते हैं की राशि निर्धारित करता है एक समय में खोलने के लिए अनुमति दी जा में findobj समारोह का उपयोग करें।

function y=limfig 
imglimit=15; 
if length(findobj('type','figure'))<imglimit 
    y=figure; 

else 
    'too many figures already open' 
    return 
end 
end 

limfig.m के रूप में और उसके बाद किसी अन्य कोड में इस छोटे से कोड को बचाने का उपयोग लाइन च = limfig च के बजाय = आंकड़ा।

+0

समस्या के बारे में सोचने का अच्छा वैकल्पिक तरीका ... –

संबंधित मुद्दे