2011-12-15 17 views
9

Tôi có một bộ nhớ Map để lưu trữ các đối tượng của mình. Tôi muốn xả bộ nhớ khi tôi hết bộ nhớ. Tôi đang thực hiện việc này ngay bây giờ:Java: trên chi phí gọi Runtime.freeMemory(), Runtime.totalMemory() và Runtime.maxMemory()

void add(K key, V value) { 
    if (underPressure()) { 
     flush(innerMap); 
    } 
    innerMap.add(k, v); 
} 

boolean underPressure() { 
    Runtime rt = Runtime.getRuntime(); 
    long maxMemory = rt.maxMemory(); 
    long freeMemory = rt.freeMemory(); 

    return (double) freeMemory/maxMemory < threshold; 
} 

Được gọi là mỗi lần chèn, giá đắt như thế nào? Theo sự hiểu biết của tôi, vì nó là một xấp xỉ, nó phải bằng cách nào đó được lưu trong bộ nhớ cache bởi jvm, nhưng không ai biết nhiều hơn về điều này không?

+1

Các máy khác biệt có thể khác nhau của nó. Làm thế nào đắt tiền là nó trên máy tính của bạn? Bạn cũng có thể kiểm tra 'return freememory

+0

Lưu ý: freeMemory chỉ cho bạn biết bạn có bao nhiêu bộ nhớ trước khi bạn cần thực hiện GC. Nó không cho bạn biết bao nhiêu sẽ được miễn phí sau khi một GC. –

+2

Cá nhân tôi sẽ đi 'final boolean underPressure()' hoặc một người nào đó sẽ phân lớp và ghi đè phương thức bằng một đoạn rap với lời bài hát thực sự tồi tệ. Sau đó, bất cứ khi nào ai đó nhìn thấy chữ ký của phương thức đó, nếu chúng không quá một độ tuổi nhất định, chúng sẽ nhận diện nó với phiên bản của Vanilla Ice và bạn sẽ cắn bụi. :-( – corsiKa

Trả lời

2

Không trực tiếp trả lời câu hỏi của bạn, nhưng như đã nói trong các ý kiến ​​freeMemory đếm bộ nhớ miễn phí chứ không phải là bộ nhớ sẽ được cung cấp sau khi một GC, do đó nếu bạn gọi freeMemory ngay trước khi GC chạy bạn có thể nghĩ bạn đang đạt đến giới hạn "underPressure" nhưng bạn cũng có thể có nhiều bộ nhớ miễn phí sau lần chạy GC tiếp theo.

cách tiếp cận khác có thể để tạo ra một đối tượng nhẹ nhàng và có thể truy cập để kiểm tra xem nó đã được tuyên bố chủ quyền GC:

cái gì đó như:

SoftReference<Object> sr = new SoftReference<Object>(new Object(),new ReferenceQueue<Object>()); 
public boolean underPressure(){ 
    if (sr.isEnqueued()) { 
     // recreate object to monitor 
     sr = new SoftReference<Object>(new Object(),new ReferenceQueue<Object>()); 
     return true; 
    } 
    return false; 
} 
+0

đây là chiến lược tuyệt vời. cảm ơn. – marcorossi

+0

câu hỏi: tại sao sử dụng ReferenceQueue? Không phải là nó đủ để sr.get() == null để kiểm tra xem có áp lực (và tái tạo sr trong trường hợp đó là tốt)? – marcorossi

3

Tại sao không sử dụng JMXBeans để làm điều này. Nó được thiết kế để đơn giản hóa loại này hoạt động ..

Từ các tài liệu ...

API cung cấp quyền truy cập vào các thông tin như:

Number of classes loaded and threads running 
Virtual machine uptime, system properties, and JVM input arguments 
Thread state, thread contention statistics, and stack trace of live threads 
Memory consumption 
Garbage collection statistics 
Low memory detection 
On-demand deadlock detection 
Operating system information 

Cụ thể xem mã ví dụ trong MemoryPoolMXBean

+0

Âm thanh giống như đúng nơi để xem. cám ơn vì sự gợi ý. – marcorossi

+0

@Jayan, Phải, nhưng điều này không thực sự * trả lời * câu hỏi ... – Pacerier

5

Vì Java 7 không cần phải thăm dò bộ nhớ miễn phí nữa. Có thể đăng ký cho một sự kiện thu gom rác thải. Xem bài đăng này: http://www.fasterj.com/articles/gcnotifs.shtml

Vì vậy, cách tốt nhất tôi có thể nghĩ đến là kiểm tra bộ nhớ miễn phí sau khi thu gom rác và sau đó giải phóng thêm dung lượng, nếu cần.

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