成都心情
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)
積分與排名
積分 - 634264
排名 - 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 模型初探(13698)
評論排行榜
1.?德國申根商務簽證攻略(成都版)(36)
2.?OSWorkflow 探索(29)
3.?北漂找工作經歷(26)
4.?使用Memory Analyzer tool(MAT)分析內存泄漏(一)(23)
5.?開源面向對象數據庫 db4o 之旅: 初識 db4o“db4o 之旅(一)”(21)
使用Memory Analyzer tool(MAT)分析內存泄漏(二)
前言的前言
寫blog就是好,在大前提下可以想說什么寫什么,不像投稿那么字字斟酌。上周末回了趟成都辦事,所以本文來遲了。K117從達州經由達成線往成都方向走的時候,發現鐵路邊有條河,盡管我現在也不知道其名字,但已被其深深的陶醉。河很寬且水流平緩,河邊山丘森林密布,民房星星點點的分布在河邊,河里偶爾些小船。當時我就在想,在這里生活是多么的愜意,夏天還可以下去暢游一番,閑來無事也可垂釣。唉,越來越討厭北漂了。
前言
在
使用Memory Analyzer tool(MAT)分析內存泄漏(一)
中,我介紹了內存泄漏的前因后果。在本文中,將介紹MAT如何根據heap dump分析泄漏根源。由于測試范例可能過于簡單,很容易找出問題,但我期待借此舉一反三。
一開始不得不說說ClassLoader,本質上,它的工作就是把磁盤上的類文件讀入內存,然后調用java.lang.ClassLoader.defineClass方法告訴系統把內存鏡像處理成合法的字節碼。Java提供了抽象類ClassLoader,所有用戶自定義類裝載器都實例化自ClassLoader的子類。system class loader在沒有指定裝載器的情況下默認裝載用戶類,在Sun Java 1.5中既sun.misc.Launcher$AppClassLoader。更詳細的內容請參看下面的資料。
準
備heap dump
請看下面的Pilot類,沒啥特殊的。
/**
* Pilot class
*
@author
rosen jiang
*/
package
org.rosenjiang.bo;
public
class
Pilot{
String name;
int
age;
public
Pilot(String a,
int
b){
name
=
a;
age
=
b;
}
}
然后再看OOMHeapTest類,它是如何撐破heap dump的。
/**
* OOMHeapTest class
*
@author
rosen jiang
*/
package
org.rosenjiang.test;
import
java.util.Date;
import
java.util.HashMap;
import
java.util.Map;
import
org.rosenjiang.bo.Pilot;
public
class
OOMHeapTest {
public
static
void
main(String[] args){
oom();
}
private
static
void
oom(){
Map
<
String, Pilot
>
map
=
new
HashMap
<
String, Pilot
>
();
Object[] array
=
new
Object[
1000000
];
for
(
int
i
=
0
; i
<
1000000
; i
++
){
String d
=
new
Date().toString();
Pilot p
=
new
Pilot(d, i);
map.put(i
+
"
rosen jiang
"
, p);
array[i]
=
p;
}
}
}
是的,上面構造了很多的Pilot類實例,向數組和map中放。由于是Strong Ref,GC自然不會回收這些對象,一直放在heap中直到溢出。當然在運行前,先要在Eclipse中配置VM參數-XX:+HeapDumpOnOutOfMemoryError。好了,一會兒功夫內存溢出,控制臺打出如下信息。
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid3600.hprof
Heap dump file created
[
78233961 bytes in 1.995 secs
]
Exception in thread
"
main
"
java.lang.OutOfMemoryError: Java heap space
java_pid3600.hprof既是heap dump,可以在OOMHeapTest類所在的工程根目錄下找到。
MAT安裝
話分兩頭說,有了heap dump還得安裝MAT。可以在http://www.eclipse.org/mat/downloads.php選擇合適的方式安裝。安裝完成后切換到Memory Analyzer視圖。在Eclipse的左上角有Open Heap Dump按鈕,按照剛才說的路徑找到java_pid3600.hprof文件并打開。解析hprof文件會花些時間,然后會彈出向導,直接Finish即可。稍后會看到下圖所示的界面。
MAT工具分析了heap dump后在界面上非常直觀的展示了一個餅圖,該圖深色區域被懷疑有內存泄漏,可以發現整個heap才64M內存,深色區域就占了99.5%。接下來是一個簡短的描述,告訴我們main線程占用了大量內存,并且明確指出system class loader加載的"java.lang.Thread"實例有內存聚集,并建議用關鍵字"java.lang.Thread"進行檢查。所以,MAT通過簡單的兩句話就說明了問題所在,就算使用者沒什么處理內存問題的經驗。在下面還有一個"Details"鏈接,在點開之前不妨考慮一個問題:為何對象實例會聚集在內存中,為何存活(而未被GC)?是的——Strong Ref,那么再走近一些吧。
點擊了"Details"鏈接之后,除了在上一頁看到的描述外,還有Shortest Paths To the Accumulation Point和Accumulated Objects部分,這里說明了從GC root到聚集點的最短路徑,以及完整的reference chain。觀察Accumulated Objects部分,java.util.HashMap和java.lang.Object[1000000]實例的retained heap(size)最大,在上一篇文章中我們知道retained heap代表從該類實例沿著reference chain往下所能收集到的其他類實例的shallow heap(size)總和,所以明顯類實例都聚集在HashMap和Object數組中了。這里我們發現一個有趣的現象,既Object數組的shallow heap和retained heap竟然一樣,通過
Shallow and retained sizes
一文可知,數組的shallow heap和一般對象(非數組)不同,依賴于數組的長度和里面的元素的類型,對數組求shallow heap,也就是求數組集合內所有對象的shallow heap之和。好,再來看org.rosenjiang.bo.Pilot對象實例的shallow heap為何是16,因為對象頭是8字節,成員變量int是4字節、String引用是4字節,故總共16字節。
接著往下看,來到了Accumulated Objects by Class區域,顧名思義,這里能找到被聚集的對象實例的類名。org.rosenjiang.bo.Pilot類上頭條了,被實例化了290,325次,再返回去看程序,我承認是故意這么干的。還有很多有用的報告可用來協助分析問題,只是本文中的例子太簡單,也用不上。以后如有用到,一定撰文詳細敘述。
又是
perm gen
我們在上一篇文章中知道,perm gen是個異類,里面存儲了類和方法數據(與class loader有關)以及interned strings(字符串駐留)。在heap dump中沒有包含太多的perm gen信息。那么我們就用這些少量的信息來解決問題吧。
看下面的代碼,利用interned strings把perm gen撐破了。
/**
* OOMPermTest class
*
@author
rosen jiang
*/
package
org.rosenjiang.test;
public
class
OOMPermTest {
public
static
void
main(String[] args){
oom();
}
private
static
void
oom(){
Object[] array
=
new
Object[
10000000
];
for
(
int
i
=
0
; i
<
10000000
; i
++
){
String d
=
String.valueOf(i).intern();
array[i]
=
d;
}
}
}
控制臺打印如下的信息,然后把java_pid1824.hprof文件導入到MAT。其實在MAT里,看到的狀況應該和“OutOfMemoryError: Java heap space”差不多(用了數組),因為heap dump并沒有包含interned strings方面的任何信息。只是在這里需要強調,使用intern()方法的時候應該多加注意。
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid1824.hprof
Heap dump file created
[
121273334 bytes in 2.845 secs
]
Exception in thread
"
main
"
java.lang.OutOfMemoryError: PermGen space
倒是在思考如何把class loader撐破廢了些心思。經過嘗試,發現使用ASM來動態生成類才能達到目的。ASM(http://asm.objectweb.org)的主要作用是處理已編譯類(compiled class),能對已編譯類進行生成、轉換、分析(功能之一是實現動態代理),而且它運行起來足夠的快和小巧,文檔也全面,實屬居家必備之良品。ASM提供了core API和tree API,前者是基于事件的方式,后者是基于對象的方式,類似于XML的SAX、DOM解析,但是使用tree API性能會有損失。既然下面要用到ASM,這里不得不啰嗦下已編譯類的結構,包括:
1、修飾符(例如public、private)、類名、父類名、接口和annotation部分。
2、類成員變量聲明,包括每個成員的修飾符、名字、類型和annotation。
3、方法和構造函數描述,包括修飾符、名字、返回和傳入參數類型,以及annotation。當然還包括這些方法或構造函數的具體Java字節碼。
4、常量池(constant pool)部分,constant pool是一個包含類中出現的數字、字符串、類型常量的數組。
已編譯類和原來的類源碼區別在于,已編譯類只包含類本身,內部類不會在已編譯類中出現,而是生成另外一個已編譯類文件;其二,已編譯類中沒有注釋;其三,已編譯類沒有package和import部分。
這里還得說說已編譯類對Java類型的描述,對于原始類型由單個大寫字母表示,Z代表boolean、C代表char、B代表byte、S代表short、I代表int、F代表float、J代表long、D代表double;而對類類型的描述使用內部名(internal name)外加前綴L和后面的分號共同表示來表示,所謂內部名就是帶全包路徑的表示法,例如String的內部名是java/lang/String;對于數組類型,使用單方括號加上數據元素類型的方式描述。最后對于方法的描述,用圓括號來表示,如果返回是void用V表示,具體參考下圖。
下面的代碼中會使用ASM core API,注意接口ClassVisitor是核心,FieldVisitor、MethodVisitor都是輔助接口。ClassVisitor應該按照這樣的方式來調用:visit visitSource? visitOuterClass? ( visitAnnotation | visitAttribute )*( visitInnerClass | visitField | visitMethod )* visitEnd。就是說visit方法必須首先調用,再調用最多一次的visitSource,再調用最多一次的visitOuterClass方法,接下來再多次調用visitAnnotation和visitAttribute方法,最后是多次調用visitInnerClass、visitField和visitMethod方法。調用完后再調用visitEnd方法作為結尾。
注意ClassWriter類,該類實現了ClassVisitor接口,通過toByteArray方法可以把已編譯類直接構建成二進制形式。由于我們要動態生成子類,所以這里只對ClassWriter感興趣。首先是抽象類原型:
/**
*
@author
rosen jiang
* MyAbsClass class
*/
package
org.rosenjiang.test;
public
abstract
class
MyAbsClass {
int
LESS
=
-
1
;
int
EQUAL
=
0
;
int
GREATER
=
1
;
abstract
int
absTo(Object o);
}
其次是自定義類加載器,實在沒法,ClassLoader的defineClass方法都是protected的,要加載字節數組形式(因為toByteArray了)的類只有繼承一下自己再實現。
/**
*
@author
rosen jiang
* MyClassLoader class
*/
package
org.rosenjiang.test;
public
class
MyClassLoader
extends
ClassLoader {
public
Class defineClass(String name,
byte
[] b) {
return
defineClass(name, b,
0
, b.length);
}
}
最后是測試類。
/**
*
@author
rosen jiang
* OOMPermTest class
*/
package
org.rosenjiang.test;
import
java.util.ArrayList;
import
java.util.List;
import
org.objectweb.asm.ClassWriter;
import
org.objectweb.asm.Opcodes;
public
class
OOMPermTest {
public
static
void
main(String[] args)
{
OOMPermTest o
=
new
OOMPermTest();
o.oom();
}
private
void
oom()
{
try
{
ClassWriter cw
=
new
ClassWriter(
0
);
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC
+
Opcodes.ACC_ABSTRACT,
"
org/rosenjiang/test/MyAbsClass
"
,
null
,
"
java/lang/Object
"
,
new
String[] {});
cw.visitField(Opcodes.ACC_PUBLIC
+
Opcodes.ACC_FINAL
+
Opcodes.ACC_STATIC,
"
LESS
"
,
"
I
"
,
null
,
new
Integer(
-
1
)).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC
+
Opcodes.ACC_FINAL
+
Opcodes.ACC_STATIC,
"
EQUAL
"
,
"
I
"
,
null
,
new
Integer(
0
)).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC
+
Opcodes.ACC_FINAL
+
Opcodes.ACC_STATIC,
"
GREATER
"
,
"
I
"
,
null
,
new
Integer(
1
)).visitEnd();
cw.visitMethod(Opcodes.ACC_PUBLIC
+
Opcodes.ACC_ABSTRACT,
"
absTo
"
,
"
(Ljava/lang/Object;)I
"
,
null
,
null
).visitEnd();
cw.visitEnd();
byte
[] b
=
cw.toByteArray();
List
<
ClassLoader
>
classLoaders
=
new
ArrayList
<
ClassLoader
>
();
while
(
true
) {
MyClassLoader classLoader
=
new
MyClassLoader();
classLoader.defineClass(
"
org.rosenjiang.test.MyAbsClass
"
, b);
classLoaders.add(classLoader);
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
不一會兒,控制臺就報錯了。
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid3023.hprof
Heap dump file created
[
92593641 bytes in 2.405 secs
]
Exception in thread
"
main
"
java.lang.OutOfMemoryError: PermGen space
打開java_pid3023.hprof文件,注意看下圖的Classes: 88.1k和Class Loader: 87.7k部分,從這點可看出class loader加載了大量的類。
更進一步分析,點擊上圖中紅框線圈起來的按鈕,選擇Java Basics——Class Loader Explorer功能。打開后能看到下圖所示的界面,第一列是class loader名字;第二列是class loader已定義類(defined classes)的個數,這里要說一下已定義類和已加載類(loaded classes)了,當需要加載類的時候,相應的class loader會首先把請求委派給父class loader,只有當父class loader加載失敗后,該class loader才會自己定義并加載類,這就是Java自己的“雙親委派加載鏈”結構;第三列是class loader所加載的類的實例數目。
在Class Loader Explorer這里,能發現class loader是否加載了過多的類。另外,還有Duplicate Classes功能,也能協助分析重復加載的類,在此就不再截圖了,可以肯定的是MyAbsClass被重復加載了N多次。
最后
其實MAT工具非常的強大,上面故弄玄虛的范例代碼根本用不上MAT的其他分析功能,所以就不再描述了。其實對于OOM不只我列舉的兩種溢出錯誤,還有多種其他錯誤,但我想說的是,對于perm gen,如果實在找不出問題所在,建議使用JVM的-verbose參數,該參數會在后臺打印出日志,可以用來查看哪個class loader加載了什么類,例:“[Loaded org.rosenjiang.test.MyAbsClass from org.rosenjiang.test.MyClassLoader]”。
全文完。
參考資料
memoryanalyzer Blog
java類加載器體系結構
ClassLoader
請注意!引用、轉貼本文應注明原作者:Rosen Jiang 以及出處:
http://www.tkk7.com/rosen
posted on 2010-06-13 16:13
Rosen
閱讀(121240)
評論(19)
編輯
收藏
所屬分類:
Java 基礎
評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)[未登錄]
2010-06-13 16:31
Jet
好文章啊,支持一直寫下去~~
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-06-14 14:11
滴水
很棒,幾種分類測試讓人更加深刻的理解了JVM的內存分配機制。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-06-14 14:50
BeanSoft
經典文章!
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-06-14 18:12
Rosen
@Jet
@滴水
@BeanSoft
感謝各位的關注!非常感謝。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)[未登錄]
2010-06-22 14:58
benbenming
OutOfMemory一直是一個頭疼的問題。
兩篇文章,附帶多個鏈接文章,我來來回回讀了兩天。
受益匪淺。
我也去用用MAT,到時候還需要你的指點。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-06-22 15:29
Rosen
@benbenming
welcome,都是一個積累的過程。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-11-18 09:54
yygy
我用上面的例子,eclipse3.2.2+jdk1.5.0_16,在eclipse.ini 里加-XX:+HeapDumpOnOutOfMemoryError,運行時報java.lang.OutOfMemoryError: Java heap space,但沒產生hprof文件,請問博主是不是還有其它什么要配的
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-11-18 12:16
Rosen
@yygy
未觀察過Eclipse的dump(猜想你是在進行Eclipse插件開發)。建議你在Eclipse社區中尋找答案。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-11-18 14:17
yygy
@Rosen
博主寫的先要在Eclipse中配置VM參數-XX:+HeapDumpOnOutOfMemoryError,這個是指在eclipse.ini 里配的嗎?沒有進行插件開發,只是在eclipse下進行測試。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2010-11-18 14:21
Rosen
@yygy
請參考
http://wiki.eclipse.org/index.php/MemoryAnalyzer
中的Getting a Heap Dump章節,我是在tomcat啟動參數中加的,而不是eclipse.ini。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2013-06-16 22:00
woyaowenzi
好文章啊。忍不住留言。和大神合個影,咔嚓。。。
后面的一部分沒怎么看懂。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2014-03-16 17:25
tp7309
好文是必須要頂的。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2014-04-14 18:21
moyue
為什么我用的時候,我想要查看Thread Details 但是它下面是空的,什么都沒有? 怎么查看線程的細節?
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2015-08-04 16:01
honghui.li
河很寬且水流平緩,河邊山丘森林密布,民房星星點點的分布在河邊,河里偶爾些小船。
很像隆盛鎮
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2015-11-11 15:36
JDongfeng
好文章,頂一個。
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)
2016-01-04 18:17
ll
好長……
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)[未登錄]
2016-05-06 16:49
James
麻煩問下我打開hprof文件時候報錯了,麻煩問下要怎樣配置,錯誤如下:
An internal error occurred during: "Parsing heap dump from 'E:\workspace\Test\java_pid6600.hprof'".
Java heap space
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)[未登錄]
2016-05-15 15:41
fox
把虛擬內存改的比文件大就行了@James
回復
更多評論
#
re: 使用Memory Analyzer tool(MAT)分析內存泄漏(二)[未登錄]
2016-08-13 13:16
dddd
樓主可以去看看一篇jvm的連載 公眾號 ITmenghuo
回復
更多評論
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
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
主站蜘蛛池模板:
久久国产免费直播
|
国产成人精品免费视频软件
|
24小时免费看片
|
国产乱子伦精品免费无码专区
|
国产成人综合亚洲AV第一页
|
亚洲男女性高爱潮网站
|
阿v免费在线观看
|
国产亚洲精品AAAA片APP
|
中国一级特黄的片子免费
|
1000部夫妻午夜免费
|
91精品国产亚洲爽啪在线影院
|
国产一级一毛免费黄片
|
国产精品1024永久免费视频
|
国产男女猛烈无遮挡免费视频网站
|
日韩精品无码免费视频
|
亚洲高清免费视频
|
好猛好深好爽好硬免费视频
|
真人做A免费观看
|
亚洲国产综合专区在线电影
|
一级毛片aaaaaa免费看
|
亚洲国产V高清在线观看
|
亚洲av成人中文无码专区
|
亚洲国产成人久久一区久久
|
国产精品亚洲综合一区在线观看
|
成年免费a级毛片
|
免费无码A片一区二三区
|
在线播放亚洲第一字幕
|
2020久久精品亚洲热综合一本
|
免费福利网站在线观看
|
亚洲视频在线观看视频
|
亚洲欧美日韩中文二区
|
久久免费看黄a级毛片
|
亚洲?V无码乱码国产精品
|
亚洲精品中文字幕无码蜜桃
|
亚洲国产精品综合久久网各
|
中文字幕免费在线
|
久久久久久亚洲精品影院
|
色欲A∨无码蜜臀AV免费播
|
亚洲一卡2卡3卡4卡国产网站
|
日韩免费三级电影
|
免费的黄色网页在线免费观看
|