<nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>

    <bdo id="rub96"></bdo>

      1. <track id="rub96"><div id="rub96"></div></track>
        <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>

            <nobr id="rub96"><address id="rub96"><big id="rub96"></big></address></nobr>
          1. <menuitem id="rub96"><strong id="rub96"><menu id="rub96"></menu></strong></menuitem>
            <dl id="rub96"><source id="rub96"><tr id="rub96"></tr></source></dl>
            1. <tbody id="rub96"><div id="rub96"></div></tbody>
              1. <bdo id="rub96"><optgroup id="rub96"></optgroup></bdo>
              2. <bdo id="rub96"><dfn id="rub96"><dd id="rub96"></dd></dfn></bdo>
                1. <option id="rub96"><source id="rub96"></source></option>
                2. <bdo id="rub96"></bdo>

                    <p id="rub96"><tr id="rub96"></tr></p>
                  1. <tbody id="rub96"></tbody>

                    <bdo id="rub96"></bdo>

                  2. <option id="rub96"><source id="rub96"></source></option>

                    <bdo id="rub96"><optgroup id="rub96"><dd id="rub96"></dd></optgroup></bdo>
                      <track id="rub96"></track>

                        <bdo id="rub96"></bdo>
                      1. <option id="rub96"><p id="rub96"><tr id="rub96"></tr></p></option>

                          <bdo id="rub96"></bdo>
                          1. <track id="rub96"></track>
                            1. <track id="rub96"></track>
                                  <bdo id="rub96"></bdo>
                                  <option id="rub96"></option>

                                      1. <track id="rub96"><span id="rub96"></span></track>

                                          <option id="rub96"></option>

                                          1. 
                                            
                                              <option id="rub96"><span id="rub96"></span></option>
                                              <bdo id="rub96"><address id="rub96"></address></bdo>
                                              <option id="rub96"><source id="rub96"></source></option>
                                                <nobr id="rub96"><address id="rub96"></address></nobr>
                                              1. <nobr id="rub96"><optgroup id="rub96"><big id="rub96"></big></optgroup></nobr>
                                                <track id="rub96"></track>

                                                <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>
                                                1. 成都心情

                                                    BlogJava :: 首頁 ::  :: 聯系 :: 聚合  :: 管理 ::
                                                    98 隨筆 :: 2 文章 :: 501 評論 :: 1 Trackbacks
                                                  使用 Memory Analyzer tool(MAT)分析內存泄漏(一)(以下簡稱前文)中說到:“Soft Ref(軟引用)對應軟可達性,只要有足夠的內存,就一直保持對象,直到發現內存吃緊且沒有Strong Ref時才回收對象。一般可用來實現緩存,通過java.lang.ref.SoftReference類實現。”
                                                  由于照本宣科,所以我一廂情愿的認為只要Strong Ref不可達,那么GC會自動回收Soft Ref可達的對象。正好最近項目上遇到一個舊版本DWR引起的內存泄漏(新版已修正),由于不愿更新到DWR的最新版本,所以想用Soft Ref來實現。可惜,到最后還是失敗了,原因在于沒正確使用Soft Ref,那么如何正確使用,在這里聊聊。

                                                  由于前文中有提到Weak Ref有個java.util.WeakHashMap實現類,所以就從它的源代碼入手吧。WeakHashMap內部是一個Entry[],而Entry是繼承了WeakReference并實現Map.Entry接口的靜態類,類聲明:private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V>。好了,由此可知,Entry實際上是WeakReference的子類,每次實例化Entry也就是在實例化WeakReference,在構造函數中調用super(key, queue)為WeakReference傳遞標識(key)和ReferenceQueue實例(queue)。ReferenceQueue和WeakReference是聯合使用的,作用是當WeakReference所引用的對象被回收后,可以通過WeakReference的poll()來得到WeakReference,但是請注意,如果再對得到的WeakReference進行get(),結果將是null,因為被Weak Ref的對象本身已經被回收。接著再看WeakHashMap的put(K key, V value)方法,該方法又關聯調用了私有方法expungeStaleEntries(),expungeStaleEntries()的注釋表明,該方法是用來刪除失效Entry的,這里調用了ReferenceQueue的poll()方法來找出被回收的對象(已被Weak Ref),然后清除,并縮小鍵-值映射關系的數目。根據觀察,例如remove(Object key)、size()、get(Object key)這些經常使用的方法,內部都優先調用了expungeStaleEntries()。由此可以見,在程序運行中很可能會引起被Weak Ref的對象的回收,所以每次操作都要進行WeakReference的poll(),而后續的清除工作還得手工編碼完成。

                                                  好,有了WeakHashMap的實現經驗,開始實現自己的SoftReference吧。

                                                  Pilot類。
                                                  /**
                                                   * Pilot class
                                                   * 
                                                  @author rosen jiang
                                                   
                                                  */

                                                  package org.rosenjiang.bo;

                                                  public class Pilot{
                                                      
                                                  private String name;
                                                      
                                                  private int age;
                                                      
                                                      
                                                  public String getName() {
                                                          
                                                  return name;
                                                      }
                                                      
                                                  public void setName(String name) {
                                                          
                                                  this.name = name;
                                                      }
                                                      
                                                  public int getAge() {
                                                          
                                                  return age;
                                                      }
                                                      
                                                  public void setAge(int age) {
                                                          
                                                  this.age = age;
                                                      }
                                                  }

                                                  SoftRefedPilot類,模擬WeakHashMap的Entry。

                                                  /**
                                                   * SoftRefedPilot class
                                                   * 
                                                  @author rosen jiang
                                                   
                                                  */

                                                  package org.rosenjiang.bo;

                                                  import java.lang.ref.ReferenceQueue;
                                                  import java.lang.ref.SoftReference;

                                                  public class SoftRefedPilot extends SoftReference<Pilot> {
                                                      
                                                  public int key;
                                                      
                                                      
                                                  public SoftRefedPilot(int key, Pilot referent, ReferenceQueue<Pilot> q) {
                                                          
                                                  super(referent, q);
                                                          
                                                  this.key = key;
                                                      }
                                                  }

                                                  測試類TestSoftReference。

                                                  /**
                                                   * TestSoftReference class
                                                   * 
                                                  @author rosen jiang
                                                   
                                                  */

                                                  package org.rosenjiang.test;

                                                  import java.lang.ref.ReferenceQueue;
                                                  import java.util.HashMap;
                                                  import java.util.Map;
                                                  import org.rosenjiang.bo.Pilot;
                                                  import org.rosenjiang.bo.SoftRefedPilot;

                                                  public class TestSoftReference {

                                                      
                                                  public static void main(String[] args) {
                                                          soft();
                                                      }
                                                      
                                                      
                                                  static void soft(){
                                                          Map
                                                  <Integer, SoftRefedPilot> map = new HashMap<Integer, SoftRefedPilot>();
                                                          ReferenceQueue
                                                  <Pilot> queue = new ReferenceQueue<Pilot>();
                                                          
                                                  int i = 0;
                                                          
                                                  while (i < 10000000) {
                                                              Pilot p 
                                                  = new Pilot();
                                                              map.put(i, 
                                                  new SoftRefedPilot(i, p, queue));
                                                              
                                                  //p = null;
                                                              SoftRefedPilot pollref = (SoftRefedPilot) queue.poll();
                                                              
                                                  if (pollref != null) {//找出被軟引用回收的對象
                                                                  
                                                  //以key為標志,從map中移除
                                                                  map.remove(pollref.key);
                                                              }
                                                              i
                                                  ++;
                                                          }
                                                          System.out.println(
                                                  "done");
                                                      }
                                                  }

                                                  好了,在JVM上加入-XX:+PrintGC參數觀察GC信息吧。

                                                  [GC 55120K->54791K(65088K), 0.0307371 secs]
                                                  [GC 58887K->58558K(65088K), 0.0313663 secs]
                                                  [Full GC 62654K->52534K(65088K), 0.3171671 secs]
                                                  [GC 56630K->56301K(65088K), 0.0278301 secs]
                                                  [GC 60397K->60068K(65088K), 0.0303315 secs]
                                                  [Full GC 64164K->55894K(65088K), 0.3330122 secs]
                                                  [GC 59990K->59660K(65088K), 0.0273494 secs]
                                                  [Full GC 63756K->63179K(65088K), 0.3415388 secs]
                                                  [Full GC 64640K->43968K(65088K), 0.3204639 secs]
                                                  [GC 48064K->47735K(65088K), 0.0329379 secs]

                                                  可以看到,當heap達到64m,隨即被Full GC,正如前文中說到的那樣,內存吃緊的時候,Soft Ref開始進行清理,另外從主觀感受和客觀日志表明,在Full GC的時候,的確比一般的GC要慢得多,貌似有10倍的差距。所以,利用Soft Ref來做緩存,這個效率還得重新考慮。

                                                  請注意!引用、轉貼本文應注明原作者:Rosen Jiang 以及出處: http://www.ymeg.top/rosen



                                                  posted on 2010-06-22 15:27 Rosen 閱讀(8671) 評論(2)  編輯  收藏 所屬分類: Java 基礎

                                                  評論

                                                  # re: 使用SoftReference軟引用 2010-06-22 17:43 BeanSoft
                                                  Java里面的Reference還有javax.naming.Reference, 開發JNDI的時候可能會用到, 說實在的, 干了這么多年, 一直還是對Java核心不太懂.

                                                  public class DAO implements IDAO, Serializable, Referenceable, ObjectFactory {

                                                  public void printAddr() {
                                                  System.out.println(this);
                                                  }

                                                  public Reference getReference() throws NamingException {
                                                  Reference ref = new Reference(super.getClass().getName(), "jndi.DAO",
                                                  null);

                                                  ref.add(new StringRefAddr("user", "BeanSoft 測試"));

                                                  return ref;
                                                  }

                                                  public Object getObjectInstance(Object refObj, Name name, Context nameCtx,
                                                  Hashtable env) throws Exception {
                                                  Reference ref = (Reference) refObj;
                                                  String cn = ref.getClassName();
                                                  IDAO pd = null;

                                                  if ((cn.equals("jndi.IDAO"))
                                                  || (cn.equals("jndi.DAO"))) {
                                                  pd = new jndi.DAO();
                                                  }

                                                  System.out.println(ref.get("user"));

                                                  if (pd == null) {
                                                  return null;
                                                  }

                                                  return pd;
                                                  }

                                                  }  回復  更多評論
                                                    

                                                  # re: 使用SoftReference軟引用 2010-06-23 09:47 Rosen
                                                  @BeanSoft
                                                  JNDI,基本沒有這種需求,所以不知道還有javax.naming.Reference,老大補充得不錯。至于Java核心,在一般的企業中還是很少關注,畢竟還是以具體業務為主。  回復  更多評論
                                                    


                                                  只有注冊用戶登錄后才能發表評論。


                                                  網站導航:
                                                   
                                                  精准平特三肖
                                                  <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>

                                                  <bdo id="rub96"></bdo>

                                                    1. <track id="rub96"><div id="rub96"></div></track>
                                                      <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>

                                                          <nobr id="rub96"><address id="rub96"><big id="rub96"></big></address></nobr>
                                                        1. <menuitem id="rub96"><strong id="rub96"><menu id="rub96"></menu></strong></menuitem>
                                                          <dl id="rub96"><source id="rub96"><tr id="rub96"></tr></source></dl>
                                                          1. <tbody id="rub96"><div id="rub96"></div></tbody>
                                                            1. <bdo id="rub96"><optgroup id="rub96"></optgroup></bdo>
                                                            2. <bdo id="rub96"><dfn id="rub96"><dd id="rub96"></dd></dfn></bdo>
                                                              1. <option id="rub96"><source id="rub96"></source></option>
                                                              2. <bdo id="rub96"></bdo>

                                                                  <p id="rub96"><tr id="rub96"></tr></p>
                                                                1. <tbody id="rub96"></tbody>

                                                                  <bdo id="rub96"></bdo>

                                                                2. <option id="rub96"><source id="rub96"></source></option>

                                                                  <bdo id="rub96"><optgroup id="rub96"><dd id="rub96"></dd></optgroup></bdo>
                                                                    <track id="rub96"></track>

                                                                      <bdo id="rub96"></bdo>
                                                                    1. <option id="rub96"><p id="rub96"><tr id="rub96"></tr></p></option>

                                                                        <bdo id="rub96"></bdo>
                                                                        1. <track id="rub96"></track>
                                                                          1. <track id="rub96"></track>
                                                                                <bdo id="rub96"></bdo>
                                                                                <option id="rub96"></option>

                                                                                    1. <track id="rub96"><span id="rub96"></span></track>

                                                                                        <option id="rub96"></option>

                                                                                        1. 
                                                                                          
                                                                                            <option id="rub96"><span id="rub96"></span></option>
                                                                                            <bdo id="rub96"><address id="rub96"></address></bdo>
                                                                                            <option id="rub96"><source id="rub96"></source></option>
                                                                                              <nobr id="rub96"><address id="rub96"></address></nobr>
                                                                                            1. <nobr id="rub96"><optgroup id="rub96"><big id="rub96"></big></optgroup></nobr>
                                                                                              <track id="rub96"></track>

                                                                                              <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>
                                                                                                <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>

                                                                                                <bdo id="rub96"></bdo>

                                                                                                  1. <track id="rub96"><div id="rub96"></div></track>
                                                                                                    <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>

                                                                                                        <nobr id="rub96"><address id="rub96"><big id="rub96"></big></address></nobr>
                                                                                                      1. <menuitem id="rub96"><strong id="rub96"><menu id="rub96"></menu></strong></menuitem>
                                                                                                        <dl id="rub96"><source id="rub96"><tr id="rub96"></tr></source></dl>
                                                                                                        1. <tbody id="rub96"><div id="rub96"></div></tbody>
                                                                                                          1. <bdo id="rub96"><optgroup id="rub96"></optgroup></bdo>
                                                                                                          2. <bdo id="rub96"><dfn id="rub96"><dd id="rub96"></dd></dfn></bdo>
                                                                                                            1. <option id="rub96"><source id="rub96"></source></option>
                                                                                                            2. <bdo id="rub96"></bdo>

                                                                                                                <p id="rub96"><tr id="rub96"></tr></p>
                                                                                                              1. <tbody id="rub96"></tbody>

                                                                                                                <bdo id="rub96"></bdo>

                                                                                                              2. <option id="rub96"><source id="rub96"></source></option>

                                                                                                                <bdo id="rub96"><optgroup id="rub96"><dd id="rub96"></dd></optgroup></bdo>
                                                                                                                  <track id="rub96"></track>

                                                                                                                    <bdo id="rub96"></bdo>
                                                                                                                  1. <option id="rub96"><p id="rub96"><tr id="rub96"></tr></p></option>

                                                                                                                      <bdo id="rub96"></bdo>
                                                                                                                      1. <track id="rub96"></track>
                                                                                                                        1. <track id="rub96"></track>
                                                                                                                              <bdo id="rub96"></bdo>
                                                                                                                              <option id="rub96"></option>

                                                                                                                                  1. <track id="rub96"><span id="rub96"></span></track>

                                                                                                                                      <option id="rub96"></option>

                                                                                                                                      1. 
                                                                                                                                        
                                                                                                                                          <option id="rub96"><span id="rub96"></span></option>
                                                                                                                                          <bdo id="rub96"><address id="rub96"></address></bdo>
                                                                                                                                          <option id="rub96"><source id="rub96"></source></option>
                                                                                                                                            <nobr id="rub96"><address id="rub96"></address></nobr>
                                                                                                                                          1. <nobr id="rub96"><optgroup id="rub96"><big id="rub96"></big></optgroup></nobr>
                                                                                                                                            <track id="rub96"></track>

                                                                                                                                            <nobr id="rub96"><optgroup id="rub96"></optgroup></nobr>
                                                                                                                                            1. 重庆快乐10分网址 手机牛牛明牌抢庄规律 广东十一选五胆拖投注表 黑龙江11选5开奖数据 mlb棒球直播平台 天易棋牌游戏下载 北京pk赛车是正规的吗 a7娱乐客户端 日韩美女动态壁纸 正规棋牌平台排行榜 网上棋牌赌博通比牛牛 双色球稳赚不赔的玩法 大嘴棋牌黄了 辽宁快乐12走势图 任选基本走势 微信关注任务赚钱是真的吗 快速时时计算方法