2011-09-08 9 views
7

thể trùng lặp:
Catching java.lang.OutOfMemoryErrorCó phải là một ý tưởng tồi để nắm bắt OutOfMemoryError không?

OutOfMemoryError là:

Ném khi Java Virtual Machine không thể phân bổ một đối tượng vì nó được ra khỏi bộ nhớ, và không nhiều bộ nhớ có thể được cung cấp bởi bộ thu gom rác

Java nói:

An Lỗi là một lớp con của Throwable cho biết vấn đề nghiêm trọng mà một ứng dụng hợp lý không nên cố gắng nắm bắt. Hầu hết các lỗi là điều kiện bất thường.

này cảm thấy như thính giác:

Nếu bạn đang chết đuối, là hợp lý, bạn không nên cố gắng bơi lên để giữ đầu của bạn trên mặt nước. Cái chết thường là kết quả của các điều kiện bất thường từ .

Hãy tưởng tượng một tình huống mà một người đang chạy dịch vụ. Vì một lý do nào đó, một ứng dụng khác trên cùng một máy chủ đang ăn nhiều bộ nhớ, gây ra một OOM bất ngờ trong dịch vụ của bạn. Có phải đó là một ý tưởng tồi để cố gắng giảm mức tiêu thụ bộ nhớ của dịch vụ này để duy trì cho người dùng không?

Hoặc có điều gì đó cơ bản hơn xảy ra ở cấp JVM ngăn cản việc thực hiện giải pháp như vậy sau khi OOM đã được ném không?

+0

@aix Tôi có thể cắt một vài tham chiếu đến một số cấu trúc dữ liệu bằng cách đặt chúng thành null ngay cả khi tôi không lưu chúng đúng cách trong khi vẫn ổn với điều đó trong các tình huống kịch tính. – JVerstry

+0

@dogbane Tham chiếu của bạn không trả lời được câu hỏi của tôi, câu hỏi này không trùng lặp. – JVerstry

+0

Một sự tương tự tốt hơn sẽ là: Lái xe của bạn bắt lửa. Đừng cố gắng tiếp tục và tiếp cận điểm đến của bạn. Kéo lên vai cứng. – Jim

Trả lời

0

Vấn đề ở đây là do OOM là lỗi không nên xảy ra trong các trường hợp bình thường. Bằng cách bắt nó và cố gắng giải phóng bộ nhớ, bạn có thể che khuất một số loại rò rỉ hoặc hành vi không mong muốn ở nơi khác.

Nếu bạn nhận được OOM, có lẽ vì bạn không định cấu hình JVM để sử dụng nhiều bộ nhớ hơn.

+0

Đồng ý, nhưng tôi có thể đăng nhập vấn đề đó sau khi phát hành bộ nhớ và gọi gc bản thân mình. Nó không phải là không thể. – JVerstry

+1

Nếu bạn có thể sửa chữa nó, và bạn biết tại sao lỗi xảy ra và nó là hợp pháp sau đó bằng mọi cách làm như vậy. Nhưng hầu hết thời gian, khi bạn nhận được một OOM bạn sẽ không biết và nó sẽ rất khó để phục hồi bởi vì bạn sẽ tìm thấy bạn đang rất hạn chế như những gì bạn có thể làm một khi máy ảo của bạn là hết bộ nhớ. –

3

Như bạn trích dẫn

Ném khi Java Virtual Machine không thể phân bổ một đối tượng vì nó được ra khỏi bộ nhớ, và không có thêm bộ nhớ có thể được cung cấp bởi các nhà sưu tập rác

Vào thời điểm đó bạn đang say. Mô tả đó ngụ ý rằng Java/JVM không thể có đủ tài nguyên để hoạt động, và nếu điều đó là đúng, thực thi mã Java nhiều hơn để sửa chữa vấn đề sẽ là vấn đề.

Tương tự tốt là xe của bạn hết xăng và bạn muốn khắc phục điều đó bằng cách đạp máy gia tốc.

Một giải pháp tốt hơn là để làm quy hoạch năng lực và chắc chắn rằng

1) các máy chủ của bạn có đủ bộ nhớ để làm công việc của họ
2) Các dịch vụ chạy trên các máy chủ của bạn hoạt động trong vòng spec và không tiêu thụ nhiều hơn một lượng tài nguyên nhất định.

+0

"JVM không còn chạy đúng" hoặc không có tài nguyên để chạy đúng cách? – JVerstry

+0

thực sự là thứ hai, đã chỉnh sửa câu trả lời của tôi. – hvgotcodes

+0

Đó là những gì tôi đang suy nghĩ quá, do đó, nó sẽ không hoàn toàn không thể hoặc không hợp lý để (ít nhất) cố gắng để tiết kiệm trong ngày. – JVerstry

-1

Đó là một ý tưởng tồi. Chủ yếu là vì OutOfMemoryError là một số Error không phải là số Exception - Lỗi "cho biết các vấn đề nghiêm trọng mà một ứng dụng hợp lý không nên cố bắt."

Thay vào đó, phân tích các tình huống có thể bạn và áp dụng các bản sửa lỗi dựa trên thông tin được cung cấp trong này PDF

+1

Ok, nhưng nếu bạn có thể sửa chữa máy bay bay để tránh tai nạn thì sao? Có lý do nào để không làm như vậy không? Đó là câu hỏi của tôi ... – JVerstry

+0

Người đàn ông, thật là một sự tương tự! Vì vậy, một vụ tai nạn máy bay xảy ra do một số điều kiện mà hầu hết thời gian là ngoài tầm kiểm soát của con người. Vì vậy, có những thủ tục khẩn cấp được xác định để một số linh hồn có thể được cứu. Tương tự như vậy một ứng dụng nên có cảnh báo sớm tại chỗ nếu nó là quan trọng và cần phải có một quá trình phục hồi - nếu hợp lý. Nếu bạn ra ngoài để bắt 'OutOfMemoryError', bạn sẽ bắt được nó ở đâu? và phần lớn thời gian khi bạn bắt được nó, bạn không thể làm được gì nhiều. Giống như một chiếc máy bay bị rơi ở giữa Đại Tây Dương, ngay cả khi bạn có dù có cơ hội sống sót là 0 –

-1

Thật là vô ích. Bởi vì tại thời điểm lỗi được bắt, bạn có thể quá thiếu bộ nhớ heap mà bất kỳ tạo đối tượng mới nào cũng có thể ném ra một OOME mới. Có một khoảng nhỏ như vậy trong thao tác nắm bắt có nghĩa là hành động duy nhất bạn có thể thực hiện là thoát.

thử đoạn này, và cho tôi biết những gì đầu ra của bạn là:

 import java.util.LinkedList; 
     import java.util.List; 

     public class OOMErrorTest { 


     public static void main(String[] args) { 
      List<Long> ll = new LinkedList<Long>(); 

      try { 
       long l = 0; 
       while(true){ 
        ll.add(new Long(l++)); 
       } 
      } catch(OutOfMemoryError oome){   
       System.out.println("Error catched!!"); 
       System.out.println("size:" +ll.size()); 
      } 
      System.out.println("Test finished"); 
     } 

     } 

Nhưng nói đúng, vâng, đây là những catchable.

+0

Bạn có ý gì khi phân hủy chính xác? – JVerstry

+0

Tôi có nghĩa là thổi lên. –

+1

Bạn có thể muốn kiểm tra http://stackoverflow.com/questions/2679330/catching-java-lang-outofmemoryerror sau đó – JVerstry

-1

Bạn thực sự không thể khôi phục từ OOM. Tuy nhiên, có một lý do để cố gắng nắm bắt bất cứ điều gì - đó là điều mà phe "bắt được" nói với tôi khi chúng tôi làm chính xác trong một dự án mà tôi không còn làm việc nữa - đó là lý do: cố gắng ghi lại những gì đã xảy ra. Bởi vì nếu bạn không biết những gì đã xảy ra, thật khó để tìm ra cách để phần mềm sao lưu và chạy.

Ngoài ra còn có một "lớn" nhưng vì lý do đó: nó sẽ không hoạt động bình thường.

Lỗi thường không thể được sửa từ bên trong mã đang chạy của bạn, đó là lý do tại sao có sự khác biệt đó.