成都心情
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://www.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
主站蜘蛛池模板:
亚洲精品国产成人99久久
|
亚洲欧美成人一区二区三区
|
波多野结衣久久高清免费
|
亚洲欧洲日本国产
|
中文亚洲AV片在线观看不卡
|
精品国产麻豆免费网站
|
亚洲综合免费视频
|
青柠影视在线观看免费
|
日韩免费高清一级毛片
|
亚洲日韩AV一区二区三区四区
|
jizz免费在线观看
|
久久亚洲AV成人无码国产最大
|
亚洲第一网站免费视频
|
亚洲AV永久无码精品
|
亚洲国产婷婷综合在线精品
|
日韩成人免费在线
|
久久国内免费视频
|
182tv免费视视频线路一二三
|
久久精品免费观看
|
中文字幕无线码免费人妻
|
边摸边脱吃奶边高潮视频免费
|
亚洲欧洲av综合色无码
|
亚洲日本va在线观看
|
国产成人精品日本亚洲专区6
|
亚洲理论在线观看
|
久久久久亚洲AV无码观看
|
国产亚洲3p无码一区二区
|
久久亚洲av无码精品浪潮
|
亚洲成A∨人片天堂网无码
|
国产精品美女自在线观看免费
|
大学生美女毛片免费视频
|
成人网站免费观看
|
黄页网站免费在线观看
|
在线看免费观看AV深夜影院
|
91网站免费观看
|
嘿嘿嘿视频免费网站在线观看
|
最近免费字幕中文大全视频
|
99久热只有精品视频免费看
|
最近2018中文字幕免费视频
|
最近免费中文字幕mv电影
|
日本最新免费网站
|