2017-09-23 51 views
1
class A { 
    void method1() { 
     B b = new B(); 
     C c = new C(); 

     // Option 1 
     List<Object> cachedObject = b.method1(); 
     c.method1(cachedObject); 
     c.method2(cachedObject); 

     // Option 2 
     c.method1(b.method1()); 
     c.method2(b.method1()); 
    } 
} 

class B { 
    List<Object> method1() { 
    } 
} 

class C { 
    void method1(List<Object> a) { 
    } 

    void method2(List<Object> a) { 
    } 
} 

在選項2中,每次獲取對象,並在參數c.method1()可用於垃圾收集返回練得更好地比較後在選項1中,我們緩存對象並在兩個方法調用c.method1()和c.method2()中使用它,因爲在c.method1()和c.method2()調用之間會發生耗時的操作,因此緩存的對象在此期間仍然被引用,並且不可用於垃圾回收。保持參照對象爲未來的方法調用或長方法

從內存利用率的角度來看,考慮到b.method1()返回的對象是巨大的(500MB +),哪個選項效果會更好?

+0

有一件事是肯定的,垃圾收集不會發生,因爲*耗時的操作* ..它依賴於對象的引用類型保持。 – nullpointer

+0

有了這樣一個通用的問題,答案几乎「取決於」。人們可以想象根據一種績效指標或另一種績效指標更好的情況。 – the8472

回答

0

在內存利用率&性能之間有一條很好的線路。正確的答案真的取決於你的情況。這裏有一些問題,我會問...

  • 什麼是你的記憶力的限制?能否讓這個對象導致你的JVM用完堆空間?
  • 您的性能要求是什麼?此對象是否需要一段時間才能創建並重新創建它,從而使您的應用程序的速度減慢到不可接受的程度?
  • 垃圾回收永遠不會得到保證,因此您將同時在內存中使用這兩個對象的風險是什麼?
  • 您需要使用此對象多少次/地點?它會在單獨的線程中傳遞並異步使用,還是會在用途之間存在很大差距?

我想提供的一個解決方案是看Java的WeakReference類。這個類允許你維護一個不妨礙垃圾回收的對象。每當你想使用它,你會做一個空檢查,如果它是垃圾收集,你可以重新創建它。當你絕對不希望你的大對象在內存中有多個實例時,這是有用的,因爲一旦舊引用被垃圾收集,弱引用將僅爲空。

+0

當我們使用選項2時,我們遇到了生產中的一個問題。創建對象非常耗時(從數據存儲中提取)並且對象體積很大。當多個線程開始調用該方法時,我們每個方法調用都會創建這樣的大對象(兩次),並且很快我們的服務器就會隨着OOM而死。轉向選項1會提高性能,但我想知道是否會使內存利用率變差。 – Viraj

+0

您的問題太過簡單,無法代表複雜的生產環境。最好只嘗試和衡量差異,而不是猜測會發生什麼。 – the8472

相關問題