ข้อผิดพลาด: การใช้งาน C stack ใกล้ถึงขีด จำกัด มากเกินไป


88

ฉันพยายามเรียกใช้โค้ดวนซ้ำที่ค่อนข้างลึกใน R และมันทำให้ฉันมีข้อผิดพลาดนี้:

ข้อผิดพลาด: การใช้งาน C stack ใกล้ถึงขีด จำกัด มากเกินไป

ผลลัพธ์ของฉันCStack_info()คือ:

Cstack_info()
    size    current  direction eval_depth 
67108864       8120          1          2 

ฉันมีหน่วยความจำมากมายในเครื่องฉันแค่พยายามหาวิธีเพิ่ม CStack สำหรับ R

แก้ไข: มีคนขอตัวอย่างที่ทำซ้ำได้ นี่คือตัวอย่างโค้ดพื้นฐานที่ทำให้เกิดปัญหา วิ่ง f (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

@mnel นิพจน์ซ้อนความลึกสแต็กการป้องกันตัวชี้และสแต็ก C เป็นสามสิ่งที่แยกจากกัน (แต่เกี่ยวข้องกัน)
zwol

ขอบคุณมากสำหรับการตอบกลับที่รวดเร็วของคุณ Zack ฉันคิดว่าคำตอบของคุณอาจเป็นสำหรับ Linux OS? ฉันกำลังใช้งาน Windows 7 64 บิตสิ่งนั้นเปลี่ยนแปลงไปหรือไม่ ขอขอบคุณอีกครั้งสำหรับความช่วยเหลือ
user2045093

2
Googling ข้อความแสดงข้อผิดพลาดแสดงให้เห็นว่าที่ผ่านมาสิ่งนี้มักเป็นข้อผิดพลาดในรหัสผู้ใช้ดังนั้นคุณควรลดปัญหาของคุณเป็นตัวอย่างง่ายๆที่ทำซ้ำได้และโพสต์ไว้ที่นี่
Martin Morgan

2
ฉันไม่แน่ใจว่ามีข้อผิดพลาดในโค้ดเลย นี่เป็นเพียงกรณีของความน่าจะเป็นที่ในทางทฤษฎีอาจจบลงด้วยการวนซ้ำที่ไม่มีที่สิ้นสุด f (1,1) คือการพลิกเหรียญ มันจะขึ้นมาตลอด สำหรับสภาวะที่ไม่ทราบระดับการเรียกซ้ำและไม่ถูกผูกไว้คุณควรคิดอะไรซ้ำ ๆ มากขึ้นโดยใช้การบันทึกผลลัพธ์ของตัวอย่างก่อนหน้า () เพื่อแจ้งการดำเนินการในอนาคต สิ่งเดียวที่คุณเสี่ยงคือหน่วยความจำเวกเตอร์หรือดิสก์หมดขึ้นอยู่กับว่าคุณจัดเก็บผลลัพธ์ค้างไว้ที่ใด การเรียกซ้ำอาจมีราคาแพงและเปราะ
Robert Casey

คำตอบ:


57

ขนาดสแต็กเป็นพารามิเตอร์ของระบบปฏิบัติการซึ่งสามารถปรับได้ตามกระบวนการ (ดูsetrlimit(2)) คุณไม่สามารถปรับได้จากภายใน R เท่าที่ฉันบอกได้ แต่คุณสามารถปรับได้จากเชลล์ก่อนเริ่ม R ด้วยulimitคำสั่ง มันทำงานดังนี้:

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

8388608 = 1024 * 8192; R กำลังพิมพ์ค่าเดียวกันกับulimit -sแต่เป็นไบต์แทนที่จะเป็นกิโลไบต์

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

หากต้องการปรับการตั้งค่านี้อย่างถาวรให้เพิ่มulimitคำสั่งลงในไฟล์เริ่มต้นเชลล์ของคุณดังนั้นจึงมีการดำเนินการทุกครั้งที่คุณเข้าสู่ระบบฉันไม่สามารถให้คำแนะนำที่เฉพาะเจาะจงมากไปกว่านั้นได้เนื่องจากขึ้นอยู่กับว่าคุณมีเชลล์และสิ่งใด ฉันไม่รู้ว่าจะทำอย่างไรเพื่อเข้าสู่สภาพแวดล้อมแบบกราฟิก (ซึ่งจะเกี่ยวข้องหากคุณไม่ได้เรียกใช้ R ภายในหน้าต่างเทอร์มินัล)


12
... unlimitedหรือเพียงแค่ตั้งค่าให้
Paul Hiemstra

1
RAppArmorแพคเกจsetrlimit(2)มีอินเตอร์เฟซที่ไปยัง ฟังก์ชันนี้อาจพร้อมใช้งานในulimitแพ็คเกจในบางจุด
krlmlr

2
ฟังก์ชันนี้ไม่มีอยู่ในแพ็คเกจRAppArmorอีกต่อไป ความคิดใดที่มันไป?
CoderGuy123

2
การแก้ไขสำหรับ Windows คืออะไร?
S.Perera

2
การเปลี่ยนขีด จำกัด จะไม่สามารถแก้ไขปัญหานี้ได้ ฟังก์ชันเรียกซ้ำจะทำงานต่อไปจนกว่าจะถึงขีด จำกัด ที่สูงขึ้น
Tom Kelly

27

ฉันสงสัยว่าไม่ว่าขีด จำกัด ของสแต็กจะจบลงด้วยการเรียกซ้ำที่ลึกเกินไป ตัวอย่างเช่นด้วย lambda = Inf, f (1) จะนำไปสู่การเรียกซ้ำทันทีโดยไม่มีกำหนด ความลึกของการเรียกซ้ำดูเหมือนจะเป็นการเดินแบบสุ่มโดยมีความเป็นไปได้ที่จะลึกลงไป, 1 - r ของการจบการเรียกซ้ำปัจจุบัน เมื่อถึงขีด จำกัด ของสแต็กคุณได้ทำขั้นตอนจำนวนมาก 'ลึกลงไป' นี่หมายความว่า r> 1/2 และเวลาส่วนใหญ่คุณจะยังคงได้รับการฟื้นฟูต่อไป

นอกจากนี้ดูเหมือนว่าเกือบจะเป็นไปได้ที่จะได้มาซึ่งโซลูชันเชิงวิเคราะห์หรืออย่างน้อยก็เป็นตัวเลขได้แม้จะเผชิญกับการวนซ้ำแบบไม่สิ้นสุด เราสามารถกำหนด p เป็นความน่าจะเป็นที่ f (1) == 1 เขียนนิพจน์โดยนัยสำหรับสถานะ 'ลูก' หลังจากการวนซ้ำครั้งเดียวและนำค่าเหล่านี้มาเทียบกับ p และแก้ p สามารถใช้เป็นโอกาสแห่งความสำเร็จในการจับคู่ครั้งเดียวจากการแจกแจงทวินาม


1
นี่คือคำตอบที่ถูกต้องซ่อนอยู่ - ตรวจสอบให้แน่ใจว่าคุณไม่ได้รับการกล่าวซ้ำอย่างลึกซึ้ง ...
Kamil S Jaron

ในกรณีของฉันข้อผิดพลาดเกิดจากการจัดหาสคริปต์ R เดียวกันหลายครั้ง (เช่นในสคริปต์ R หลายตัว) ในโครงการของฉัน
Good Will

15

ข้อผิดพลาดนี้ไม่ได้เนื่องจากหน่วยความจำเป็นเพราะการเรียกซ้ำ ฟังก์ชันกำลังเรียกตัวเอง เพื่ออธิบายประเด็นต่อไปนี้เป็นตัวอย่างขั้นต่ำของ 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")

ข้อผิดพลาด: การใช้งาน C stack 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=', ') ). เป้าหมายคือการได้รับรายการสถานะเฉพาะที่คั่นด้วยจุลภาคสำหรับแต่ละกลุ่มย่อย
Richard DiSalvo

4

ฉันพบปัญหาเดียวกันในการรับข้อผิดพลาด "การใช้สแต็ก C อยู่ใกล้กับขีด จำกัด มากเกินไป" (แม้ว่าจะมีแอปพลิเคชันอื่นที่ไม่ใช่ที่ระบุโดย user2045093 ด้านบน) ฉันลองใช้ข้อเสนอของ zwol แต่มันไม่ได้ผล

ด้วยความประหลาดใจของฉันเองฉันสามารถแก้ปัญหาได้โดยการติดตั้ง R เวอร์ชันใหม่ล่าสุดสำหรับ OS X (ปัจจุบัน: เวอร์ชัน 3.2.3) รวมทั้ง R Studio เวอร์ชันใหม่ล่าสุดสำหรับ OS X (ปัจจุบัน: 0.99.840) เนื่องจากฉัน กำลังทำงานกับ R Studio

หวังว่านี่อาจเป็นประโยชน์สำหรับคุณเช่นกัน


1
ฉันเปลี่ยนไปใช้เวอร์ชันที่สูงกว่าของ R มันใช้งานได้หนึ่งครั้ง แต่ข้อผิดพลาดปรากฏขึ้นอีกครั้งและมีความสอดคล้องกันในขณะนี้ ช่วยด้วย!
murphy1310

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

สำหรับข้อมูลของทุกคนจู่ๆฉันก็พบกับ R 3.6.1 บน Windows 7 (64 บิต) มันไม่เคยเป็นปัญหามาก่อนและตอนนี้ขีด จำกัด สแต็กดูเหมือนจะโผล่ขึ้นมาทุกที่เมื่อฉันพยายาม "บันทึก (.)" ข้อมูลหรือแม้แต่ทำ "save.image (.)" มันเหมือนกับว่าการทำให้เป็นอนุกรมกำลังพัดกองเหล่านี้ออกไป

ฉันกำลังพิจารณาอย่างจริงจังว่าจะลดกลับไปที่ 3.6.0 ไม่ได้เกิดขึ้นที่นั่น


1

ของฉันอาจเป็นกรณีที่ไม่เหมือนใคร แต่อาจช่วยได้ไม่กี่คนที่มีปัญหานี้:

กรณีของฉันไม่มีส่วนเกี่ยวข้องกับการใช้พื้นที่ แต่ R ยังคงให้:
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

หากคุณใช้ plot_ly ให้ตรวจสอบว่าคุณกำลังส่งคอลัมน์ใด ดูเหมือนว่าสำหรับคอลัมน์ POSIXdt / ct คุณต้องใช้ as.character () ก่อนที่จะส่งต่อไปยัง plotly มิฉะนั้นคุณจะได้รับข้อยกเว้นนี้!


0

ฉันมักจะใส่source("path/to/file/thefile.R")บรรทัดแสดงความคิดเห็นไว้ที่ด้านบนของสคริปต์ R เช่นthefile.Rดังนั้นฉันจึงสามารถคัดลอกวางลงในเทอร์มินัลเพื่อเรียกใช้งานได้อย่างง่ายดาย ฉันได้รับข้อผิดพลาดนี้หากฉันลืมที่จะแสดงความคิดเห็นในบรรทัดเนื่องจากการเรียกใช้ไฟล์จะเรียกใช้ไฟล์ซึ่งเรียกใช้ไฟล์ซึ่งเรียกใช้ไฟล์ ...

หากเป็นสาเหตุวิธีแก้ก็ง่าย ๆ : แสดงความคิดเห็นตามบรรทัด


0

ไม่แน่ใจว่าถ้าเราอีกครั้งในรายการประเด็นที่นี่ leaflet()แต่มันเกิดขึ้นกับผมด้วย ผมพยายามที่จะ map dataframe ซึ่งเป็นคอลัมน์ของชั้นเรียนdate POSIXltการเปลี่ยนกลับเพื่อPOSIXctแก้ไขปัญหา


0

บน Linux ฉันได้เพิ่มขนาดของสแต็กและความทรงจำ memlock อย่างถาวรโดยทำดังนี้:

sudo vi /etc/security/limits.conf 

จากนั้นเพิ่มบรรทัดต่อไปนี้ที่ท้ายไฟล์

* soft memlock unlimited
* hard memlock unlimited

* soft stack unlimited
* hard stack unlimited
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.