成都心情
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)
積分與排名
積分 - 635655
排名 - 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)分析內存泄漏(二)(121270)
2.?使用Memory Analyzer tool(MAT)分析內存泄漏(一)(75980)
3.?Java 中的位運算(31049)
4.?Ajax輪詢以及Comet模式—寫在Servlet 3.0發布之前(15655)
5.?RBAC 模型初探(13709)
評論排行榜
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://m.tkk7.com/rosen
posted on 2010-06-22 15:27
Rosen
閱讀(9134)
評論(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
主站蜘蛛池模板:
成人亚洲国产va天堂
|
亚洲日本一区二区
|
亚洲国产日韩a在线播放
|
91热成人精品国产免费
|
亚洲黄色网址在线观看
|
日韩av无码久久精品免费
|
色婷婷亚洲十月十月色天
|
亚洲人成网站在线观看青青
|
国产亚洲女在线线精品
|
亚洲视频免费在线播放
|
国产亚洲精久久久久久无码77777
|
亚洲国产精品久久久久网站
|
高清在线亚洲精品国产二区
|
亚洲精品无码久久久久sm
|
a毛片视频免费观看影院
|
女人让男人免费桶爽30分钟
|
亚洲中文字幕无码一区二区三区
|
xxxxx做受大片在线观看免费
|
成人午夜视频免费
|
国产偷国产偷亚洲高清人
|
亚洲中久无码不卡永久在线观看
|
亚美影视免费在线观看
|
国产精品国产自线拍免费软件
|
国产精品亚洲成在人线
|
免费精品无码AV片在线观看
|
亚洲一区二区三区免费观看
|
免费人成毛片动漫在线播放
|
处破痛哭A√18成年片免费
|
精品久久久久久亚洲中文字幕
|
最近2022中文字幕免费视频
|
国产精品亚洲自在线播放页码
|
99国产精品免费视频观看
|
久久精品国产99国产精品亚洲
|
免费看a级黄色片
|
波多野结衣免费一区视频
|
亚洲人成免费网站
|
亚洲国产精品综合久久网络
|
亚洲AV网一区二区三区
|
亚洲日韩一页精品发布
|
岛国av无码免费无禁网站
|
中文字幕亚洲综合久久综合
|