成都心情
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://m.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ⅴ免费网站
|
亚洲日韩国产精品乱
|
性生大片视频免费观看一级
|
免费h黄肉动漫在线观看
|
国产精品亚洲综合一区在线观看
|
免费人妻无码不卡中文字幕18禁
|
日本特黄特色AAA大片免费
|
日本最新免费不卡二区在线
|
日韩亚洲变态另类中文
|
国产高潮久久免费观看
|
亚洲人成在线播放网站
|
午夜免费福利视频
|
亚洲日本国产乱码va在线观看
|
日韩在线播放全免费
|
亚洲精品天堂在线观看
|
四虎成人免费大片在线
|
亚洲美女视频免费
|
嫖丰满老熟妇AAAA片免费看
|
亚洲熟妇自偷自拍另欧美
|
免费A级毛片在线播放不收费
|
亚洲免费网站在线观看
|
亚洲AV永久无码区成人网站
|
在线观看的免费网站无遮挡
|
久久福利青草精品资源站免费
|
69式国产真人免费视频
|
18禁止看的免费污网站
|
亚洲欧美自偷自拍另类视
|
高清在线亚洲精品国产二区
|
国产成人精品亚洲2020
|
免费国产成人高清视频网站
|
亚洲精品无码成人
|
美腿丝袜亚洲综合
|
精品国产无限资源免费观看
|
亚洲AV色无码乱码在线观看
|
中文字幕无码一区二区免费
|
亚洲中文字幕久久精品无码2021
|
午夜国产羞羞视频免费网站
|
18禁超污无遮挡无码免费网站
|