2012-04-09 24 views
14

Tôi đang viết một hàm sẽ tự gọi lên tới khoảng 5000 lần. Ofcourse, tôi nhận được một StackOverflowException. Có cách nào để tôi có thể viết lại mã này theo một cách khá đơn giản không ?:Java: Cách tránh StackOverflowException

void checkBlocks(Block b, int amm) { 

    //Stuff that might issue a return call 

    Block blockDown = (Block) b.getRelative(BlockFace.DOWN); 
    if (condition) 
     checkBlocks(blockDown, amm); 


    Block blockUp = (Block) b.getRelative(BlockFace.UP); 
    if (condition) 
     checkBlocks(blockUp, amm); 

    //Same code 4 more times for each side 

} 

Nhân tiện, giới hạn của hàm chúng ta có thể gọi là gì?

Cảm ơn!

+0

http://stackoverflow.com/questions/214741/what-is -a-stack-overflow-error –

Trả lời

17

Có thể sử dụng ngăn xếp?

void checkBlocks(Block b, int amm) { 
    Stack<Block> blocks = new Stack<Block>(); 
    blocks.push(b); 
    while (!blocks.isEmpty()) { 
    b = blocks.pop(); 
    Block blockDown = (Block) b.getRelative(BlockFace.DOWN); 
    if (condition) 
     blocks.push(block); 
    Block blockUp = (Block) b.getRelative(BlockFace.UP); 
    if (condition) 
     blocks.push(block); 
    } 
} 
+0

Cảm ơn rất nhiều, hoạt động rất tốt. Lớp đó có lẽ sẽ rất tiện dụng sau này. Ty! –

0

Bạn có thể tăng kích thước ngăn xếp bằng cách sử dụng -Xss4m.

+0

Nhưng nếu kích thước bảng chỉ tiếp tục tăng thì sao?Tôi nghĩ anh ấy đã nhận ra điều này và không hỏi làm thế nào để tăng kích thước ngăn xếp, mà là làm thế nào để cấu trúc lại mã! – barsju

0

Bạn có thể đặt "Chặn" của bạn vào hàng đợi/ngăn xếp và lặp lại miễn là các khối có sẵn.

0

Rõ ràng là bạn có được StackOverflow với yếu tố phân nhánh như vậy của đệ quy của bạn. Trong các ngôn ngữ khác, nó có thể đạt được by Tail Call Optimization. Nhưng tôi cho rằng vấn đề của bạn cần một cách khác để giải quyết.

Lý tưởng nhất là bạn thực hiện một số kiểm tra trên Chặn. Có lẽ bạn có thể có được danh sách của tất cả các khối và kiểm tra từng người trong số họ lặp đi lặp lại?

4

kích thước ngăn xếp mặc định trong java là 512kb. nếu bạn vượt quá chương trình sẽ chấm dứt ném StackOverflowException

bạn có thể tăng kích thước ngăn xếp bằng cách thông qua một đối số JVM: -Xss1024k

tại ngăn xếp kích thước là 1024kb. bạn có thể đưa ra giá trị cao hơn dựa trên môi trường của bạn

Tôi không nghĩ rằng chúng ta có thể lập trình thay đổi này

0

Trong hầu hết các trường hợp đệ quy được sử dụng trong một cách sai lầm. Bạn không nên có một ngoại lệ ngăn xếp trên luồng. Phương thức của bạn không có kiểu trả về/giá trị. Làm cách nào để bạn đảm bảo Khối b ban đầu của mình hợp lệ?

Nếu bạn đang sử dụng đệ quy, trả lời cho mình những câu dưới đây:

  • neo đệ quy của tôi là gì (khi để tôi dừng lại với đệ quy) bước đệ quy của tôi
  • là gì (làm thế nào để giảm bớt số lượng của tôi tính toán)

Ví dụ:

  • n! => n * n-1!

neo đệ quy của tôi là n == 2 (kết quả là 2), vì vậy tôi có thể tính toán tất cả kết quả bắt đầu từ neo này.

bước đệ quy của tôi là n-1 (vì vậy mỗi bước tôi nhận được gần gũi hơn với các giải pháp (và trong thực tế này để neo đệ quy của tôi))

Các vấn đề liên quan