2012-09-16 30 views
5

Tôi đã phát triển một ứng dụng trình duyệt web J2ME, nó hoạt động tốt. Tôi đang thử nghiệm mức tiêu thụ bộ nhớ của nó. Dường như với tôi rằng nó có rò rỉ bộ nhớ, vì đường cong màu xanh biểu thị bộ nhớ tiêu thụ của bộ nhớ (bộ công cụ không dây) đạt tới bộ nhớ được cấp phát tối đa (là 687768 byte) mỗi 7 yêu cầu được thực hiện bởi trình duyệt, (tức là khi người dùng cuối điều hướng trong trình duyệt web từ trang này sang trang khác trong 7 trang) sau đó bộ thu gom rác chạy và giải phóng bộ nhớ được cấp phát.Có phải rò rỉ bộ nhớ nếu bộ thu gom rác chạy bất thường?

Câu hỏi của tôi là:

  • là nó rò rỉ bộ nhớ khi bộ gom rác chạy tự động mỗi navigation 7 trang?
  • Tôi có cần chạy bộ thu gom rác (System.gc()) theo cách thủ công một lần cho mỗi yêu cầu để ngăn bộ nhớ được cấp phát tối đa không?

hãy hướng dẫn cho tôi, nhờ

+0

Nếu bộ nhớ bị rò rỉ, bộ thu gom rác sẽ không giải phóng bộ nhớ được cấp phát? – nnnnnn

+0

Nếu bạn biết danh sách các đối tượng cần thiết và không muốn tạo quá nhiều rác, bạn có thể gộp các đối tượng này và tái sử dụng chúng. Điều này sẽ làm giảm tần suất chạy GC. – Vikdor

Trả lời

3

Để xác định xem nó là một rò rỉ bộ nhớ, bạn sẽ cần phải quan sát nó nhiều hơn nữa.

Từ mô tả của bạn, tức là khi đạt tới bộ nhớ tối đa, GC sẽ khởi động và có thể giải phóng bộ nhớ cho ứng dụng của bạn để chạy, có vẻ như không có rò rỉ.

Ngoài ra bạn không nên gọi GC mình kể từ

  1. nó chỉ là một dấu hiệu
  2. khả năng có thể ảnh hưởng đến các thuật toán cơ bản ảnh hưởng đến hiệu quả của nó.

Bạn nên tập trung vào lý do tại sao ứng dụng của bạn cần quá nhiều bộ nhớ trong một thời gian ngắn như vậy.

+0

Cảm ơn Cratylus, Trên thực tế, ứng dụng thực hiện một số hoạt động mã hóa theo yêu cầu, các hoạt động này đáng để tiêu thụ lượng bộ nhớ này, tuy nhiên, làm thế nào tôi có thể giải phóng bộ nhớ được phân bổ vì tôi cần kích thước bộ nhớ cố định cho một lớp cụ thể mỗi lần Tôi điều hướng đến một trang. tức là tôi chạy cùng một thuật toán cho mỗi yêu cầu. – mdawaina

+0

Hoặc bạn cần phải tăng heap của bạn, hoặc làm cho thuật toán của bạn tiết kiệm không gian hơn nếu có thể. – Cratylus

+1

@mdawaina - Bạn không/không thể "deallocate" lưu trữ trong Java - lưu trữ được khai hoang bởi GC khi không còn bất kỳ tham chiếu đến nó. Nhưng lưu trữ chỉ được khai hoang trong chu kỳ GC. –

1

Câu hỏi của tôi là: nó có bị rò rỉ bộ nhớ khi bộ thu gom rác chạy tự động mỗi 7 trang điều hướng không?

Không nhất thiết. Nó cũng có thể là:

  • đống của bạn là quá nhỏ so với kích thước của vấn đề bạn đang cố gắng để giải quyết, hoặc

  • ứng dụng của bạn được tạo ra (theo sở thích) rác với tốc độ cao.

Thực tế, với những con số bạn đã trình bày, tôi có xu hướng nghĩ rằng đây chủ yếu là vấn đề kích thước heap. Nếu khoảng thời gian giữa GC chạy giảm theo thời gian, thì R THNG sẽ là bằng chứng cho thấy rò rỉ bộ nhớ, nhưng nếu tỷ lệ vẫn ổn định, thì nó sẽ gợi ý rằng tốc độ sử dụng bộ nhớ và cải tạo là cân bằng; tức là không bị rò rỉ.

Tôi có cần chạy bộ thu gom rác (System.gc()) một lần theo yêu cầu để ngăn bộ nhớ được cấp phát tối đa không?

No. No. No. No.

Gọi System.gc() sẽ không khắc phục tình trạng rò rỉ bộ nhớ. Nếu nó là một rò rỉ bộ nhớ thực, sau đó gọi System.gc() sẽ không đòi lại bộ nhớ bị rò rỉ. Trong thực tế, tất cả các bạn sẽ làm là làm cho ứng dụng của bạn RUN A LOT SLOWER ... giả định rằng JVM không bỏ qua cuộc gọi hoàn toàn.


bằng chứng trực tiếp và gián tiếp rằng mặc định hành vi của HotSpot JVM là để tôn vinh System.gc() gọi:

Và từ mã Java 7 nguồn:

./openjdk/hotspot/src/share/vm/runtime/globals.hpp

product(bool, DisableExplicitGC, false,         \ 
      "Tells whether calling System.gc() does a full GC")    \ 

nơi false là giá trị mặc định cho tùy chọn. (Và lưu ý rằng đây là phần độc lập của hệ điều hành/M/C của cây mã.)

+0

Cảm ơn Stephen cho câu trả lời quý giá của bạn, tôi nghĩ rằng đống là nhỏ như bạn nói – mdawaina

+0

Trên thực tế System.GC bị vô hiệu hóa trên hầu hết các nền tảng, và chỉ là "gợi ý" trên phần còn lại. –

+0

@HotLicks - thực sự 1) "hầu hết các nền tảng" là một cường điệu, 2) nó được ghi nhận là gợi ý trên TẤT CẢ nền tảng và 3) Tôi đã đề cập rằng JVM có thể bỏ qua cuộc gọi: đọc lại 9 từ cuối cùng trong câu trả lời của tôi. –

0

Đó là (bán) hành vi bình thường. Dung lượng sẵn có (không được thu nhận) không được thu thập cho đến khi kích thước của heap đạt đến ngưỡng nào đó, kích hoạt chu trình thu thập.

Bạn có thể giảm tần suất chu kỳ GC bằng cách "hiểu biết nhiều hơn một chút". Ví dụ, một lỗi phổ biến trong nhiều chương trình là phân tích chuỗi bằng cách sử dụng chuỗi con để không chỉ phân tích cú pháp từ trái nhất, mà còn rút ngắn chuỗi còn lại bằng cách căn lề sang phải. Tạo một String mới cho từ này không dễ dàng tránh được, nhưng người ta có thể dễ dàng tránh lặp đi lặp lại việc tạo chuỗi "đuôi" của chuỗi gốc.

Hệ thống đang chạy.GC sẽ không thực hiện được gì - trên hầu hết các nền tảng, đây là một phiên bản không hoạt động vì nó thường bị lạm dụng.

Lưu ý rằng (bên ngoài Android chết não) bạn không thể có một "rò rỉ bộ nhớ" thực sự trong Java (trừ khi có lỗi JVM nghiêm trọng). Cái thường được gọi là "rò rỉ" trong Java là thất bại trong việc loại bỏ tất cả các tham chiếu đến các đối tượng sẽ không bao giờ được sử dụng nữa. Ví dụ, bạn có thể tiếp tục đưa dữ liệu vào một chuỗi và không bao giờ rõ ràng con trỏ đến các công cụ trên đầu xa của chuỗi đó sẽ không còn được sử dụng. Các triệu chứng kết quả là đống MINIMUM được sử dụng (tức là, kích thước ngay lập tức sau khi GC chạy) tiếp tục tăng mỗi chu kỳ.

+0

cảm ơn bạn Hot Licks, tôi đánh giá cao phần mềm answare của bạn – mdawaina

0

Thêm vào câu trả lời tuyệt vời khác:

Hình như bạn đang bối rối bộ nhớ bị rò rỉ có thu rác.

Rò rỉ bộ nhớ là khi bộ nhớ không sử dụng không thể thu gom rác vì nó vẫn có tài liệu tham khảo ở đâu đó (mặc dù chúng không được sử dụng cho bất kỳ thứ gì).

Thu gom rác là khi một phần mềm (bộ thu gom rác) tự động giải phóng bộ nhớ không bị nhiễu.

Bạn không nên gọi bộ thu gom rác theo cách thủ công vì điều đó sẽ ảnh hưởng đến hiệu suất của nó.

1

Tôi đã viết một thư viện nỗ lực hết sức để buộc GC. Như đã đề cập trước đó, System.gc() là không đồng bộ và sẽ không tự làm bất cứ điều gì. Bạn có thể muốn sử dụng thư viện này để lập hồ sơ ứng dụng của bạn và tìm ra những nơi có quá nhiều rác đang được sản xuất. Bạn có thể đọc thêm về nó trong this article nơi tôi mô tả chi tiết vấn đề GC.

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