2010-01-24 41 views
55

Tôi đang chạy một chương trình mà tôi đã viết bằng Java trong Eclipse. Chương trình có mức độ đệ quy rất sâu đối với các đầu vào rất lớn. Đối với đầu vào nhỏ hơn chương trình chạy tốt tuy nhiên khi đầu vào lớn được đưa ra, tôi nhận được lỗi sau:Lỗi tràn ngăn xếp Java - cách tăng kích thước ngăn xếp trong Eclipse?

Exception in thread "main" java.lang.StackOverflowError 

này có thể được giải quyết bằng cách tăng kích thước ngăn xếp Java và nếu như vậy, làm thế nào để làm điều này trong Eclipse?

Cập nhật:

@ Jon Skeet

Mã này được đi qua một cây phân tích cú pháp đệ quy để xây dựng một datastructure. Vì vậy, ví dụ mã sẽ làm một số công việc bằng cách sử dụng một nút trong cây phân tích cú pháp và gọi chính nó trên hai nút của trẻ, kết hợp các kết quả của chúng để đưa ra kết quả tổng thể cho cây.

Tổng chiều sâu của đệ quy phụ thuộc vào kích thước của cây phân tích nhưng mã có vẻ thất bại (không có ngăn xếp lớn hơn) khi số lượng các cuộc gọi đệ quy vào 1000.

Ngoài ra tôi khá chắc chắn mã không bị lỗi do lỗi khi hoạt động với các đầu vào nhỏ.

+7

điều gì đó sai ở đây ... stackoverflow (.com) không phải là lỗi! :-) –

Trả lời

72

Mở Cấu hình chạy cho ứng dụng của bạn (Chạy/Chạy cấu hình ..., sau đó tìm mục nhập ứng dụng trong 'ứng dụng Java').

Các luận tab có một hộp văn bản luận Vm, nhập -Xss1m (hoặc một tham số lớn hơn cho ngăn xếp kích thước tối đa). Giá trị mặc định là 512 kByte (SUN JDK 1.5 - không biết nếu nó thay đổi giữa các nhà cung cấp và phiên bản).

+2

Hãy nhận biết vấn đề này: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6316197 –

10

Thêm cờ -Xss1024k vào đối số VM.

Bạn cũng có thể tăng kích thước ngăn xếp trong mb bằng cách sử dụng -Xss1m chẳng hạn.

37

có thể có thể chữa được bằng cách tăng kích thước ngăn xếp - nhưng giải pháp tốt hơn sẽ là giải quyết cách tránh lặp lại quá nhiều. Một giải pháp đệ quy luôn có thể được chuyển đổi thành một giải pháp lặp đi lặp lại - điều này sẽ làm cho quy mô mã của bạn trở thành các đầu vào lớn hơn sạch hơn nhiều. Nếu không, bạn sẽ thực sự đoán được bao nhiêu stack để cung cấp, mà thậm chí có thể không rõ ràng từ đầu vào.

Bạn có chắc chắn rằng nó không thành công do kích thước của đầu vào thay vì một lỗi trong mã, bằng cách này? Sự đệ quy này sâu bao nhiêu?

EDIT: Được rồi, khi đã xem bản cập nhật, tôi sẽ cố gắng viết lại nó để tránh sử dụng đệ quy. Nói chung có một số Stack<T> của "mọi thứ vẫn còn làm" là một điểm khởi đầu tốt để loại bỏ đệ quy.

+4

..hoặc theo đuôi đệ quy. – BalusC

+0

Tôi không thể nhớ trạng thái đệ quy đuôi trên jvms. Cue bình luận từ tackline. –

+1

JVM chưa làm quy tắc tối ưu hóa việc thu thập đuôi. Tôi tin rằng đây là một trong những điều mà việc khái quát hóa JVM thành các ngôn ngữ không phải Java là để sửa chữa. –

3

Bạn cần có cấu hình khởi chạy bên trong Eclipse để điều chỉnh các thông số JVM.

Sau khi chạy chương trình của bạn bằng F11 hoặc Ctrl-F11, hãy mở cấu hình khởi chạy trong Chạy -> Chạy cấu hình ... và mở chương trình của bạn trong "Ứng dụng Java". Chọn khung Arguments, nơi bạn sẽ tìm thấy "đối số VM".

Đây là nơi -Xss1024k hoạt động.

Nếu bạn muốn cấu hình khởi chạy là tệp trong không gian làm việc của bạn (để bạn có thể nhấp chuột phải và chạy nó), hãy chọn ngăn Chung và chọn hộp kiểm Lưu dưới dạng - Chia sẻ tệp và duyệt đến vị trí bạn muốn tệp khởi chạy. Tôi thường có chúng trong một thư mục riêng biệt, khi chúng tôi kiểm tra chúng vào CVS.

5

tôi cũng có cùng một vấn đề khi phân tách các file định nghĩa schema (XSD) sử dụng thư viện XSOM,

tôi đã có thể để tăng bộ nhớ stack tối đa 208Mb sau đó nó cho thấy heap_out_of_memory_error mà tôi đã có thể để tăng chỉ tối đa 320MB.

cấu hình cuối cùng là -Xmx320m -Xss208m nhưng sau đó lại chạy trong một thời gian và không thành công.

Chức năng của tôi in đệ quy toàn bộ cây định nghĩa lược đồ, đáng ngạc nhiên là tệp đầu ra đã vượt qua 820Mb cho tệp định nghĩa 4 Mb (thư viện Aixm) mà lần lượt sử dụng 50 Mb thư viện định nghĩa lược đồ (ISO gml).

với điều đó tôi tin rằng tôi phải tránh đệ quy và sau đó bắt đầu lặp lại và một số cách khác để đại diện cho đầu ra, nhưng tôi gặp chút rắc rối khi chuyển đổi tất cả đệ quy đó thành lặp lại.

2

Khi đối số -Xss không thực hiện công việc thử xóa các tập tin tạm thời từ:

c:\Users\{user}\AppData\Local\Temp\. 

này đã làm các trick cho tôi.

0

Nhìn vào cây ngang theo thứ tự của Morris, sử dụng không gian cố định và chạy trong O (n) (dài hơn 3 lần so với truyền tải đệ quy bình thường của bạn - nhưng bạn tiết kiệm rất nhiều không gian). Nếu các nút có thể sửa đổi, bạn có thể lưu kết quả được tính toán của cây con khi bạn quay lại gốc của nó (bằng cách viết trực tiếp vào nút).

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