त्रुटि: सी स्टैक का उपयोग सीमा के बहुत करीब है


86

मैं आर में कुछ काफी गहरी पुनरावर्ती कोड चलाने का प्रयास कर रहा हूं और यह मुझे यह त्रुटि देता है:

त्रुटि: सी स्टैक का उपयोग सीमा के बहुत करीब है

से मेरा आउटपुट CStack_info()है:

Cstack_info()
    size    current  direction eval_depth 
67108864       8120          1          2 

मेरी मशीन पर बहुत सारी मेमोरी है, मैं सिर्फ यह पता लगाने की कोशिश कर रहा हूं कि मैं आर के लिए CStack कैसे बढ़ा सकता हूं।

संपादित करें: किसी ने एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण के लिए कहा। यहाँ कुछ बुनियादी नमूना कोड है जो समस्या का कारण बनता है। च (1,1) चल रहा है कुछ बार आपको त्रुटि मिलेगी। ध्यान दें कि मैंने पहले ही सेट किया है - max-ppsize = 500000 और विकल्प (भाव = 500000) ताकि यदि आप उन्हें सेट नहीं करते हैं तो आपको उन दो चीजों में से एक के बजाय एक त्रुटि मिल सकती है। जैसा कि आप देख सकते हैं, यहाँ पुनरावृत्ति बहुत गहरी जा सकती है और मुझे नहीं पता है कि इसे लगातार काम करने के लिए कैसे प्राप्त किया जाए। धन्यवाद।

f <- function(root=1,lambda=1) {
    x <- c(0,1);
    prob <- c(1/(lambda+1),lambda/(lambda+1));
        repeat {
      if(root == 0) {
        break;
      }
      else {
        child <- sample(x,2,replace=TRUE,prob);
        if(child[1] == 0 && child[2] == 0) {
          break;
        }
        if(child[1] == 1) {
          child[1] <- f(root=child[1],lambda);
        }
        if(child[2] == 1 && child[1] == 0) {
          child[2] <- f(root=child[2],lambda);
        }
      }
      if(child[1] == 0 && child[2] == 0) {
        break;
      }
      if(child[1] == 1 || child[2] == 1) {
        root <- sample(x,1,replace=TRUE,prob);
      }
        }
    return(root)
}

1
यह सवाल शायद पता चलता हैoptions(expressions = somethinglarge)
mnel

@ एमलाइन अभिव्यक्ति नेस्टिंग डेप्थ, पॉइंटर प्रोटेक्शन स्टैक, और सी स्टैक तीन अलग (लेकिन संबंधित) चीजें हैं।
zwol

आपकी शीघ्र प्रतिक्रिया के लिए बहुत बहुत धन्यवाद, जैक। मुझे लगता है कि आपका जवाब हालांकि लिनक्स ओएस के लिए हो सकता है? मैं वर्तमान में विंडोज 7 64 बिट चला रहा हूं, क्या इससे चीजें बदल जाती हैं? किसी भी मदद के लिए फिर से धन्यवाद।
user2045093

2
त्रुटि संदेश को देखने से पता चलता है कि अतीत में यह आमतौर पर उपयोगकर्ता कोड में एक त्रुटि रही है, इसलिए आपको संभवतः अपनी समस्या को एक सरल प्रतिलिपि प्रस्तुत करने योग्य उदाहरण में कम करना चाहिए और यहां पोस्ट करना चाहिए ।
मार्टिन मॉर्गन

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

जवाबों:


56

स्टैक आकार एक ऑपरेटिंग सिस्टम पैरामीटर है, समायोज्य प्रति-प्रक्रिया (देखें setrlimit(2))। आप इसे आर के भीतर से समायोजित नहीं कर सकते हैं जहाँ तक मैं बता सकता हूँ, लेकिन आप आर से शुरू होने से पहले इसे शेल से समायोजित कर सकते हैं, ulimitकमांड के साथ । यह इस तरह काम करता है:

$ ulimit -s # print default
8192
$ R --slave -e 'Cstack_info()["size"]'
   size 
8388608

8388608 = 1024 * 8192; आर के रूप में एक ही मूल्य मुद्रण है ulimit -s, लेकिन किलोबाइट के बजाय बाइट्स में।

$ ulimit -s 16384 # enlarge stack limit to 16 megs
$ R --slave -e 'Cstack_info()["size"]'
    size 
16777216 

इस सेटिंग में एक स्थायी समायोजन करने के लिए, ulimitकमांड को अपने शेल स्टार्टअप फ़ाइल में जोड़ें, इसलिए जब भी आप लॉग इन करें तो हर बार इसे निष्पादित किया जाए। मैं इससे अधिक विशिष्ट दिशा-निर्देश नहीं दे सकता, क्योंकि यह वास्तव में किस शेल पर निर्भर करता है और आपके पास सामान है। मुझे यह भी पता नहीं है कि इसे ग्राफिकल वातावरण में प्रवेश करने के लिए कैसे करना है (जो कि प्रासंगिक होगा यदि आप टर्मिनल विंडो के अंदर आर नहीं चला रहे हैं)।


12
... या बस इसे सेट करें unlimited
पॉल हैमस्ट्रा

1
RAppArmorपैकेज के लिए एक इंटरफेस प्रदान करता है setrlimit(2)। यह कार्यक्षमता ulimitकुछ बिंदु पर पैकेज में उपलब्ध हो सकती है ।
krlmlr

2
यह फ़ंक्शन अब RAAArmor पैकेज में मौजूद नहीं है । किसी भी विचार यह कहाँ चला गया?
कोडरगुइज़

2
विंडोज के लिए फिक्स क्या है?
एस.पेररा

2
सीमा बदलने से इसका समाधान नहीं होगा। उच्च सीमा तक पहुंचने तक एक पुनरावर्ती कार्य बस चलता रहेगा।
टॉम केली

27

मुझे संदेह है कि, स्टैक सीमा की परवाह किए बिना, आप उन पुनरावृत्तियों के साथ समाप्त हो जाएंगे जो बहुत गहरी हैं। उदाहरण के लिए, लैम्ब्डा = इन्फ, एफ (1) के साथ अनिश्चित काल के लिए तत्काल पुनरावृत्ति होती है। पुनरावृत्ति की गहराई एक यादृच्छिक चलना प्रतीत होती है, जिसमें कुछ संभावना आर गहराई तक जाने की संभावना है, 1 - वर्तमान पुनरावृत्ति को समाप्त करने की आर। जब तक आपने स्टैक सीमा को मारा है, तब तक आपने बड़ी संख्या में कदम 'गहरा' कर दिया है। इसका तात्पर्य यह है कि r> 1/2, और बहुत बड़ा समय आप बस फिर से जारी रखना चाहते हैं।

इसके अलावा, ऐसा लगता है कि अनंत पुनरावृत्ति की स्थिति में भी एक विश्लेषणात्मक या कम से कम संख्यात्मक समाधान प्राप्त करना संभव है। एक p को प्रायिकता के रूप में परिभाषित कर सकता है कि f (1) == 1, एकल पुनरावृत्ति के बाद 'चाइल्ड' स्टेट्स के लिए निहित भावों को लिखें, और इन्हें p के साथ समान करें, और हल करें। पी तो एक द्विपद वितरण से एक ही ड्रा में सफलता के अवसर के रूप में इस्तेमाल किया जा सकता है।


1
यहाँ वास्तव में सही उत्तर छिपा हुआ है - सुनिश्चित करें कि आप पुनरावृत्ति में गहरे नहीं हैं ...
कामिल एस जेरोन

मेरे मामले में, त्रुटि एक ही R स्क्रिप्ट को कई बार सोर्स करने के कारण होती है (यानी मेरे प्रोजेक्ट में कई R स्क्रिप्ट्स में)।
अच्छी विल

14

यह त्रुटि स्मृति के कारण नहीं है यह पुनरावृत्ति के कारण है । एक फंक्शन ही बुला रहा है। इस बिंदु को समझने के लिए, यहाँ 2 कार्यों का एक न्यूनतम उदाहरण दिया गया है, जो एक दूसरे को कहते हैं:

change_to_factor <- function(x){
  x <- change_to_character(x)
  as.factor(x)
} 

change_to_character <- function(x){
  x <- change_to_factor(x)
  as.character(x)
}

change_to_character("1")

त्रुटि: सी स्टैक का उपयोग 7971600 सीमा के बहुत करीब है

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


10

यह मेरे लिए एक पूरी तरह से अलग कारण से हुआ। मैंने दो कॉलमों को मिलाते हुए गलती से एक सुपरलेंग स्ट्रिंग बनाया:

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, col = "_"))

के बजाय

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, sep = "_"))

मुझे हमेशा के लिए इसका पता लगाने के लिए ले लिया क्योंकि मुझे उम्मीद नहीं थी कि पेस्ट की वजह से समस्या हो सकती है।


यहाँ भी, लेकिन मैं एक सारांश कर रहा था। मेरे पास ऐसा था summarize( states = paste0(state,collapse=', ') ):। जब मुझे कुछ ऐसा करना चाहिए था summarize( states = paste0(sort(unique(state)),collapse=', ') ):। लक्ष्य को प्रत्येक उपसमूह के लिए उपलब्ध अद्वितीय राज्यों की अल्पविराम से पृथक सूची प्राप्त करनी थी।
रिचर्ड डायस्लावो

4

मुझे "सी स्टैक का उपयोग सीमा के बहुत करीब है" त्रुटि प्राप्त करने की समान समस्या का सामना करना पड़ा (उपर्युक्त उपयोगकर्ता 2045093 द्वारा बताए गए की तुलना में किसी अन्य एप्लिकेशन के लिए)। मैंने zwol के प्रस्ताव की कोशिश की लेकिन यह कारगर नहीं हुआ।

अपने स्वयं के आश्चर्य के लिए, मैं ओएस एक्स के लिए आर के नवीनतम संस्करण (वर्तमान में: 3.2.3 संस्करण) के साथ-साथ ओएस एक्स के लिए आर स्टूडियो का नवीनतम संस्करण (वर्तमान में: 0.99.840) स्थापित करके समस्या का समाधान कर सकता हूं। आर स्टूडियो के साथ काम कर रहा हूँ।

उम्मीद है, यह आपकी कुछ मदद भी कर सकता है।


1
मैंने R के उच्च संस्करण पर स्विच किया। यह एक बार काम करता है, लेकिन त्रुटि फिर से दिखाई देती है और अब लगातार है। मदद!
मर्फी 1310

2

यहां एक मुद्दा यह हो सकता है कि आप fखुद को अंदर बुला रहे हों

plop <- function(a = 2){
  pouet <- sample(a)
  plop(pouet)
}
plop()
Erreur : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ?
Erreur pendant l'emballage (wrapup) : évaluations trop profondément imbriquées : récursion infinie / options(expressions=) ?

1

हर किसी की जानकारी के लिए, मैं विंडोज 7 (64-बिट) पर आर 3.6.1 के साथ अचानक से चल रहा हूं। यह पहले कोई समस्या नहीं थी, और अब स्टैक सीमाएं हर जगह पॉपिंग लगती हैं, जब मैं "save (।)" डेटा या यहां तक ​​कि "save.image (।)" करने की कोशिश करता हूं। यह वैसा ही है जैसे क्रमबद्धता इन ढेरों को उड़ा रही है।

मैं गंभीरता से 3.6.0 पर वापस जाने पर विचार कर रहा हूं। वहाँ नहीं हुआ।


1

मेरा शायद एक अधिक अनोखा मामला है, लेकिन इस सटीक समस्या वाले कुछ लोगों की मदद कर सकते हैं:

मेरे मामले का अंतरिक्ष उपयोग से कोई लेना-देना नहीं है, फिर भी आर ने यह दिया:
C stack usage is too close to the limit

मेरे पास एक परिभाषित फ़ंक्शन था जो आधार फ़ंक्शन का उन्नयन है:

saveRDS ()

लेकिन,
संयोग से, इस परिभाषित समारोह के saveRDS()बजाय बुलाया गया था safe_saveRDS()
इस प्रकार, उस परिभाषा के पिछले, जब कोड को लाइन विच को मिला वास्तव में उपयोग करता है saveRDS(...)(जो मूल आधार संस्करण को कॉल करता है , अपग्रेडेड नहीं), यह उपरोक्त त्रुटि देता है और कुचल जाता है।

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


0

जैसा कि मार्टिन मॉर्गन ने लिखा है ... समस्या यह है कि आप पुनरावृत्ति के अंदर बहुत गहरे हैं। यदि पुनरावृत्ति बिल्कुल नहीं जुटती है, तो आपको इसे अपने आप से तोड़ने की आवश्यकता है। मुझे उम्मीद है कि यह कोड काम करने वाला है, क्योंकि यह परीक्षण नहीं किया गया है। हालांकि यहां कम से कम बिंदु स्पष्ट होना चाहिए।

f <- function(root=1,lambda=1,depth=1) {
 if(depth > 256){
  return(NA)
 }
 x <- c(0,1);
 prob <- c(1/(lambda+1),lambda/(lambda+1));
 repeat {
  if(root == 0) {
    break;
  } else {
   child <- sample(x,2,replace=TRUE,prob);
   if(child[1] == 0 && child[2] == 0) {
     break;
   }
   if(child[1] == 1) {
     child[1] <- f(root=child[1],lambda,depth+1);
   }
   if(child[2] == 1 && child[1] == 0) {
     child[2] <- f(root=child[2],lambda,depth+1);
   }
  }
  if(child[1] == NA | child[2] == NA){
   return NA;
  }
  if(child[1] == 0 && child[2] == 0) {
    break;
  }
  if(child[1] == 1 || child[2] == 1) {
    root <- sample(x,1,replace=TRUE,prob);
  }
 }
 return(root)
}

0

उसी समस्या के कारण का एक और तरीका:

library(debug)
mtrace(lapply)

पुनरावर्ती कॉल यहां स्पष्ट नहीं है।


0

यदि आप प्लॉट_ली चेक कर रहे हैं तो आप कौन से कॉलम पास कर रहे हैं। ऐसा लगता है कि POSIXdt / ct कॉलम के लिए, आपको अलग-अलग पास करने से पहले as.character () का उपयोग करना होगा या आपको यह अपवाद मिलेगा!


0

मैं अक्सर source("path/to/file/thefile.R")एक आर स्क्रिप्ट के शीर्ष पर एक टिप्पणी-आउट लाइन शामिल करता हूं , उदाहरण के लिए thefile.R, इसलिए मैं इसे चलाने के लिए टर्मिनल में आसानी से कॉपी-पेस्ट कर सकता हूं। मुझे यह त्रुटि मिलती है अगर मैं लाइन पर टिप्पणी करना भूल जाता हूं, क्योंकि फ़ाइल को चलाने से फ़ाइल चलती है, जो फ़ाइल को चलाता है, जो फ़ाइल को चलाता है, ...

यदि वह कारण है, तो समाधान सरल है: लाइन से टिप्पणी करें।

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