Lỗi: Mức sử dụng ngăn xếp C quá gần với giới hạn


87

Tôi đang cố gắng chạy một số mã đệ quy khá sâu trong R và nó tiếp tục cho tôi lỗi này:

Lỗi: Mức sử dụng ngăn xếp C quá gần với giới hạn

Đầu ra của tôi CStack_info()là:

Cstack_info()
    size    current  direction eval_depth 
67108864       8120          1          2 

Tôi có nhiều bộ nhớ trên máy của mình, tôi chỉ đang cố gắng tìm cách tăng CStack cho R.

CHỈNH SỬA: Ai đó đã yêu cầu một ví dụ có thể tái tạo. Đây là một số mã mẫu cơ bản gây ra sự cố. Chạy f (1,1) một vài lần bạn sẽ gặp lỗi. Lưu ý rằng tôi đã đặt --max-ppsize = 500000 và các tùy chọn (biểu thức = 500000), vì vậy nếu bạn không đặt chúng, bạn có thể gặp lỗi về một trong hai điều đó. Như bạn có thể thấy, đệ quy có thể đi khá sâu ở đây và tôi không biết làm thế nào để làm cho nó hoạt động nhất quán. Cảm ơn.

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
Câu hỏi này cho thấy có lẽoptions(expressions = somethinglarge)
mnel

@mnel Độ sâu lồng biểu thức, ngăn xếp bảo vệ con trỏ và ngăn xếp C là ba thứ riêng biệt (nhưng có liên quan).
zwol

Cảm ơn rất nhiều vì phản hồi nhanh chóng của bạn, Zack. Tôi nghĩ rằng câu trả lời của bạn có thể dành cho hệ điều hành Linux? Tôi hiện đang chạy Windows 7 64 bit, điều đó có thay đổi gì không? cám ơn lần nữa cho bất kì sự giúp đỡ nào.
user2045093

2
Googling thông báo lỗi cho thấy rằng trước đây đây thường là lỗi trong mã người dùng, vì vậy bạn có thể nên giảm sự cố của mình thành một ví dụ đơn giản có thể tái tạo và đăng nó ở đây.
Martin Morgan

2
Tôi không chắc có lỗi trong mã nào cả. Đây chỉ đơn giản là một trường hợp xác suất mà về lý thuyết có thể dẫn đến đệ quy vô hạn. f (1,1) về cơ bản là tung đồng xu. Nó có thể tiếp tục xuất hiện trong đầu mãi mãi. Đối với điều kiện mà mức đệ quy là không xác định và không bị giới hạn, bạn nên nghĩ ra một thứ gì đó lặp lại nhiều hơn, sử dụng ghi nhớ các kết quả mẫu () trước đó để thông báo cho các hoạt động trong tương lai. Sau đó, điều duy nhất bạn có nguy cơ là hết bộ nhớ vector hoặc đĩa, tùy thuộc vào nơi bạn đang lưu trữ kết quả tồn đọng của mình. Đệ quy có thể đắt và giòn.
Robert Casey

Câu trả lời:


56

Kích thước ngăn xếp là một tham số của hệ điều hành, có thể điều chỉnh theo quy trình (xem setrlimit(2)). Bạn không thể điều chỉnh nó từ bên trong R theo như tôi có thể nói, nhưng bạn có thể điều chỉnh nó từ shell trước khi bắt đầu R, bằng ulimitlệnh. Nó hoạt động như thế này:

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

8388608 = 1024 * 8192; R đang in giá trị giống như ulimit -s, nhưng theo byte thay vì kilobyte.

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

Để thực hiện điều chỉnh vĩnh viễn đối với cài đặt này, hãy thêm ulimitlệnh vào tệp khởi động trình bao của bạn, vì vậy lệnh được thực thi mỗi khi bạn đăng nhập. Tôi không thể đưa ra hướng cụ thể hơn thế, vì nó phụ thuộc vào chính xác trình bao bạn có và nội dung. Tôi cũng không biết làm thế nào để đăng nhập vào môi trường đồ họa (sẽ có liên quan nếu bạn không chạy R bên trong cửa sổ đầu cuối).


12
... hoặc chỉ cần đặt nó thành unlimited.
Paul Hiemstra

1
Các RAppArmorgói cung cấp một giao diện để setrlimit(2). Chức năng này có thể có sẵn trong ulimitgói vào một lúc nào đó.
krlmlr

2
Chức năng này không còn tồn tại trong gói RAppArmor . Bất kỳ ý tưởng nơi nó đã đi?
CoderGuy123

2
Bản sửa lỗi cho Windows là gì?
S.Perera

2
Thay đổi giới hạn sẽ không giải quyết được điều này. Một hàm đệ quy sẽ tiếp tục chạy cho đến khi đạt đến giới hạn cao hơn.
Tom Kelly

27

Tôi nghi ngờ rằng, bất kể giới hạn ngăn xếp, bạn sẽ kết thúc với các đệ quy quá sâu. Ví dụ, với lambda = Inf, f (1) dẫn đến một đệ quy ngay lập tức, vô thời hạn. Độ sâu của đệ quy dường như là một bước đi ngẫu nhiên, với một số xác suất r đi sâu hơn, 1 - r kết thúc đệ quy hiện tại. Khi bạn đạt đến giới hạn ngăn xếp, bạn đã thực hiện một số lượng lớn các bước 'sâu hơn'. Điều này ngụ ý rằng r> 1/2, và phần lớn thời gian bạn sẽ tiếp tục lặp lại.

Ngoài ra, có vẻ như gần như có thể thu được một giải tích hoặc ít nhất là nghiệm số ngay cả khi đối mặt với đệ quy vô hạn. Người ta có thể định nghĩa p là xác suất mà f (1) == 1, viết biểu thức ngầm định cho các trạng thái 'con' sau một lần lặp duy nhất, và cân bằng chúng với p, và giải. p sau đó có thể được sử dụng như cơ hội thành công trong một lần rút ra từ phân phối nhị thức.


1
đây thực sự là câu trả lời đúng ẩn - hãy đảm bảo rằng bạn không hiểu sâu như vậy ...
Kamil S Jaron

Trong trường hợp của tôi, lỗi là do tìm nguồn cung cấp cùng một tập lệnh R nhiều lần (tức là trong nhiều tập lệnh R) trong dự án của tôi.
Good Will

14

Lỗi này không phải do bộ nhớ mà là do đệ quy . Một hàm đang gọi chính nó. Để minh họa cho vấn đề này, đây là một ví dụ nhỏ nhất về 2 hàm gọi nhau:

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")

Lỗi: Sử dụng ngăn xếp C 7971600 quá gần với giới hạn

Các hàm sẽ tiếp tục gọi nhau một cách đệ quy và về mặt lý thuyết sẽ không bao giờ hoàn thành. Nó chỉ kiểm tra trong hệ thống của bạn để ngăn điều này xảy ra vô thời hạn và tiêu thụ tất cả các tài nguyên máy tính của máy tính của bạn. Bạn cần thay đổi các hàm để đảm bảo rằng chúng không gọi chính nó (hoặc lẫn nhau) một cách đệ quy.


10

Điều này xảy ra với tôi vì một lý do hoàn toàn khác. Tôi đã vô tình tạo một chuỗi siêu dài trong khi kết hợp hai cột:

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

thay vì

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

Đã khiến tôi mãi mãi tìm ra nó vì tôi không bao giờ mong đợi việc dán lại có thể gây ra sự cố.


Ở đây cũng vậy, nhưng tôi đang tóm tắt. Tôi đã có nó như thế này: summarize( states = paste0(state,collapse=', ') ). Khi nào tôi nên đã làm một cái gì đó như: summarize( states = paste0(sort(unique(state)),collapse=', ') ). Mục tiêu là có được một danh sách các trạng thái duy nhất được phân tách bằng dấu phẩy cho mỗi nhóm con.
Richard DiSalvo

4

Tôi gặp phải sự cố tương tự khi nhận được lỗi "Sử dụng ngăn xếp C quá gần với giới hạn" (mặc dù đối với ứng dụng khác với ứng dụng được nêu bởi user2045093 ở trên). Tôi đã thử đề xuất của zwol nhưng không thành công.

Trước sự ngạc nhiên của riêng tôi, tôi có thể giải quyết vấn đề bằng cách cài đặt phiên bản R mới nhất cho OS X (hiện tại: phiên bản 3.2.3) cũng như phiên bản R Studio mới nhất cho OS X (hiện tại: 0.99.840), kể từ khi tôi đang làm việc với R Studio.

Hy vọng rằng, điều này cũng có thể giúp ích cho bạn.


1
Tôi đã chuyển sang phiên bản cao hơn của R. Nó hoạt động một lần, nhưng lỗi xuất hiện lại và hiện nhất quán. Cứu giúp!
Murphy1310

2

Một vấn đề ở đây có thể là bạn đang gọi fbên trong

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

Đối với thông tin của mọi người, tôi đột nhiên gặp phải vấn đề này với R 3.6.1 trên Windows 7 (64-bit). Đó không phải là vấn đề trước đây và bây giờ giới hạn ngăn xếp dường như xuất hiện ở khắp mọi nơi, khi tôi cố gắng "lưu (.)" Dữ liệu hoặc thậm chí thực hiện "save.image (.)". Nó giống như việc tuần tự hóa đang thổi bay những ngăn xếp này.

Tôi đang nghiêm túc xem xét giảm trở lại 3.6.0. Đã không xảy ra ở đó.


1

Trường hợp của tôi có lẽ là một trường hợp độc đáo hơn, nhưng có thể giúp ích cho một số người gặp vấn đề chính xác này:

Trường hợp của tôi hoàn toàn không liên quan đến việc sử dụng dung lượng, vẫn R đã đưa ra:
C stack usage is too close to the limit

Tôi đã có một hàm được xác định là bản nâng cấp của hàm cơ sở:

saveRDS ()

Nhưng,
tình cờ, hàm được xác định này được gọi saveRDS()thay vì safe_saveRDS().
Do đó, vượt qua định nghĩa đó, khi mã đến dòng mà nó thực sự sử dụng saveRDS(...)(gọi là phiên bản cơ sở ban đầu, không phải phiên bản nâng cấp), nó đã đưa ra lỗi ở trên và bị nghiền nát.

Vì vậy, nếu bạn gặp lỗi đó khi gọi một số chức năng lưu, hãy xem liệu bạn có vô tình chạy qua nó hay không.


0

Như Martin Morgan đã viết ... Vấn đề là bạn đi quá sâu vào bên trong của đệ quy. Nếu đệ quy hoàn toàn không hội tụ, bạn cần phải tự phá vỡ nó. Tôi hy vọng mã này sẽ hoạt động, bởi vì nó không được thử nghiệm. Tuy nhiên ít nhất điểm nên rõ ràng ở đây.

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

Một cách khác để gây ra vấn đề tương tự:

library(debug)
mtrace(lapply)

Lời gọi đệ quy không rõ ràng ở đây.


0

Nếu bạn đang sử dụng plot_ly, hãy kiểm tra xem bạn đang chuyển những cột nào. Có vẻ như đối với các cột POSIXdt / ct, bạn phải sử dụng as.character () trước khi chuyển đến plotly hoặc bạn nhận được ngoại lệ này!


0

Tôi thường bao gồm một source("path/to/file/thefile.R")dòng chú thích ở đầu tập lệnh R thefile.R, vì vậy tôi có thể dễ dàng sao chép và dán đoạn này vào thiết bị đầu cuối để chạy nó. Tôi gặp lỗi này nếu tôi quên nhận xét ra dòng, vì chạy tệp chạy tệp, tệp nào chạy tệp, tệp nào chạy tệp, ...

Nếu đó là nguyên nhân, giải pháp rất đơn giản: bình luận ra bên ngoài.


0

Không chắc liệu chúng tôi có liệt kê các vấn đề ở đây không nhưng nó đã xảy ra với tôi leaflet(). Tôi đang cố gắng ánh xạ một khung dữ liệu trong đó một datecột thuộc loại POSIXlt. Thay đổi trở lại để POSIXctgiải quyết vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.