成都心情
BlogJava
::
首頁
:: ::
聯系
::
聚合
::
管理
::
98 隨筆 :: 2 文章 :: 501 評論 :: 1 Trackbacks
公告
本作品采用
知識共享署名-相同方式共享 2.5 中國大陸許可協議
進行許可。
(15)
給我留言
查看公開留言
查看私人留言
隨筆分類
(91)
Java EE 服務器端(13)
(rss)
Java EE 表現層及容器(12)
(rss)
Java ME(1)
(rss)
Java 基礎(10)
(rss)
MatLab(1)
(rss)
O/R Mapping(13)
(rss)
Versant db4o 中文項目(12)
(rss)
Web前端技術
(rss)
五花八門(8)
(rss)
大數據(3)
(rss)
工作流(10)
(rss)
數據庫(2)
(rss)
模式與策略(6)
(rss)
隨筆檔案
(99)
2016年7月 (2)
2016年6月 (4)
2016年5月 (3)
2016年4月 (2)
2010年7月 (1)
2010年6月 (2)
2010年5月 (3)
2010年3月 (1)
2010年1月 (1)
2009年10月 (1)
2009年9月 (1)
2009年7月 (1)
2009年6月 (1)
2009年3月 (1)
2009年2月 (1)
2008年12月 (2)
2008年9月 (1)
2008年8月 (1)
2008年7月 (1)
2008年6月 (1)
2008年4月 (1)
2008年3月 (1)
2008年1月 (1)
2007年12月 (2)
2007年10月 (1)
2007年9月 (1)
2007年8月 (1)
2007年6月 (2)
2007年5月 (1)
2007年4月 (1)
2007年2月 (1)
2007年1月 (1)
2006年12月 (1)
2006年11月 (1)
2006年10月 (1)
2006年9月 (1)
2006年8月 (1)
2006年7月 (1)
2006年6月 (1)
2006年5月 (1)
2006年4月 (1)
2006年3月 (1)
2006年2月 (1)
2006年1月 (1)
2005年12月 (1)
2005年11月 (1)
2005年10月 (1)
2005年9月 (2)
2005年8月 (37)
文章分類
(2)
我的收藏(2)
(rss)
友情鏈接
david.turing
(rss)
wyingquan的專欄
(rss)
信息安全思想
俺的豬窩~!@
喜馬拉雅的雪杉
(rss)
無聊人士
(rss)
竹十一
(rss)
老劉忙不忙
(rss)
邢紅瑞的blog
(rss)
積分與排名
積分 - 634229
排名 - 74
最新評論
1.?re: 精確截取字符串(轉載)
string=goodStr(string); 這個方法 是干什么用處的?
--JustPassoner
2.?re: 精確截取字符串(轉載)
@國家機器
六六,認識你是我等榮幸,酒瘋知己千杯燒...
--JustPassoner
3.?re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)[未登錄]
樓主可以去看看一篇jvm的連載 公眾號 ITmenghuo
--dddd
4.?re: 使用Memory Analyzer tool(MAT)分析內存泄漏(一)
小瑕疵。
圖片顯示不了。
--袁良錠
5.?re: Hadoop周刊—第 169 期
喲,又開始更新了
--救救劉書記
閱讀排行榜
1.?使用Memory Analyzer tool(MAT)分析內存泄漏(二)(121240)
2.?使用Memory Analyzer tool(MAT)分析內存泄漏(一)(75947)
3.?Java 中的位運算(31038)
4.?Ajax輪詢以及Comet模式—寫在Servlet 3.0發布之前(15639)
5.?RBAC 模型初探(13697)
評論排行榜
1.?德國申根商務簽證攻略(成都版)(36)
2.?OSWorkflow 探索(29)
3.?北漂找工作經歷(26)
4.?使用Memory Analyzer tool(MAT)分析內存泄漏(一)(23)
5.?開源面向對象數據庫 db4o 之旅: 初識 db4o“db4o 之旅(一)”(21)
使用SoftReference軟引用
在
使用 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.tkk7.com/rosen
posted on 2010-06-22 15:27
Rosen
閱讀(9119)
評論(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核心,在一般的企業中還是很少關注,畢竟還是以具體業務為主。
回復
更多評論
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關文章:
使用SoftReference軟引用
使用Memory Analyzer tool(MAT)分析內存泄漏(二)
使用Memory Analyzer tool(MAT)分析內存泄漏(一)
VSS Plugin配置FAQ(翻譯)
Jakarta-ORO 分解 IP 地址
Java 短路運算符和非短路運算符
Java 中的位運算
Java 工具,你用了嗎?(翻譯)
循證克隆
在 Eclipse 中使用 JUnit(翻譯)
Powered by:
BlogJava
Copyright © Rosen
主站蜘蛛池模板:
亚洲Aⅴ无码专区在线观看q
|
久久亚洲国产午夜精品理论片
|
亚洲视频在线免费观看
|
91精品成人免费国产
|
久久久久久亚洲精品不卡
|
人妻仑乱A级毛片免费看
|
免费吃奶摸下激烈视频
|
免费无码国产在线观国内自拍中文字幕
|
在线观看肉片AV网站免费
|
亚洲免费日韩无码系列
|
成人精品综合免费视频
|
日韩视频免费在线
|
亚洲A∨精品一区二区三区下载
|
成年女人喷潮毛片免费播放
|
亚洲国产av玩弄放荡人妇
|
日韩一级免费视频
|
一区免费在线观看
|
亚洲精品无码久久久久
|
久久久久久国产精品免费免费男同
|
水蜜桃亚洲一二三四在线
|
5555在线播放免费播放
|
亚洲人xxx日本人18
|
国产性生交xxxxx免费
|
aa毛片免费全部播放完整
|
亚洲AV无码国产精品色午友在线
|
99re6在线精品视频免费播放
|
亚洲高清美女一区二区三区
|
中文字幕乱码免费视频
|
亚洲AV日韩AV无码污污网站
|
亚洲毛片网址在线观看中文字幕
|
a色毛片免费视频
|
亚洲AV无码一区二区三区人
|
国产在线ts人妖免费视频
|
中文字幕的电影免费网站
|
亚洲天天做日日做天天看
|
毛片a级三毛片免费播放
|
xxxxxx日本处大片免费看
|
夜夜亚洲天天久久
|
真实乱视频国产免费观看
|
成全视成人免费观看在线看
|
亚洲国语在线视频手机在线
|