青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 14,  comments - 57,  trackbacks - 0
  昨天一個同事一大早在群里推薦了一個google project上的開源內(nèi)存分配器(http://code.google.com/p/google-perftools/),據(jù)說google的很多產(chǎn)品都用到了這個內(nèi)存分配庫,而且經(jīng)他測試,我們的游戲客戶端集成了這個最新內(nèi)存分配器后,F(xiàn)PS足足提高了將近10幀左右,這可是個了不起的提升,要知道3D組的兄弟忙了幾周也沒見這么大的性能提升。

如果我們自己本身用的crt提供的內(nèi)存分配器,這個提升也算不得什么。問題是我們內(nèi)部系統(tǒng)是有一個小內(nèi)存管理器的,一般來說小內(nèi)存分配的算法都大同小異,現(xiàn)成的實(shí)現(xiàn)也很多,比如linux內(nèi)核的slab、SGI STL的分配器、ogre自帶的內(nèi)存分配器,我們自己的內(nèi)存分配器也和前面列舉的實(shí)現(xiàn)差不多。讓我們來看看這個項(xiàng)目有什么特別的吧。

一、使用方法

打開主頁,由于公司網(wǎng)絡(luò)禁止SVN從外部更新,所以只能下載了打包的源代碼。解壓后,看到有個doc目錄,進(jìn)去,打開使用文檔,發(fā)現(xiàn)使用方法極為簡單:
To use TCMalloc, just link TCMalloc into your application via the "-ltcmalloc" linker flag.再看算法,也沒什么特別的,還是和slab以及SGI STL分配器類似的算法。
unix環(huán)境居然只要鏈接這個tcmalloc庫就可以了!,太方便了,不過我手頭沒有l(wèi)inux環(huán)境,文檔上也沒提到windows環(huán)境怎么使用,
打開源代碼包,有個vs2003解決方案,打開,隨便挑選一個測試項(xiàng)目,查看項(xiàng)目屬性,發(fā)現(xiàn)僅僅有2點(diǎn)不同:
1、鏈接器命令行里多了
  "..\..\release\libtcmalloc_minimal.lib",就是鏈接的時候依賴了這個內(nèi)存優(yōu)化庫。
2、鏈接器->輸入->強(qiáng)制符號引用 多了 __tcmalloc。
這樣就可以正確的使用tcmalloc庫了,測試了下,測試項(xiàng)目運(yùn)行OK!

二、如何替換CRT的malloc

從前面的描述可知,項(xiàng)目強(qiáng)制引用了__tcmalloc, 搜索了測試代碼,沒發(fā)現(xiàn)用到_tcmalloc相關(guān)的函數(shù)和變量,這個選項(xiàng)應(yīng)該是為了防止dll被優(yōu)化掉(因?yàn)榇a里沒有什么地方用到這個dll的符號)。
初看起來,鏈接這個庫后,不會影響任何現(xiàn)有代碼:我們沒有引用這個Lib庫的頭文件,也沒有使用過這個dll的導(dǎo)出函數(shù)。那么這個dll是怎么優(yōu)化應(yīng)用程序性能的呢?
實(shí)際調(diào)試,果然發(fā)現(xiàn)問題了,看看如下代碼
    void* pData = malloc(100);
00401085 6A 64            push        64h 
00401087 FF 15 A4 20 40 00 call        dword ptr [__imp__malloc (4020A4h)]
跟蹤 call malloc這句,step進(jìn)去,發(fā)現(xiàn)是
78134D09 E9 D2 37 ED 97   jmp         `anonymous namespace'::LibcInfoWithPatchFunctions<8>::Perftools_malloc (100084E0h)
果然,從這里開始,就跳轉(zhuǎn)到libtcmalloc提供的Perftools_malloc了。
原來是通過API掛鉤來實(shí)現(xiàn)無縫替換系統(tǒng)自帶的malloc等crt函數(shù)的,而且還是通過大家公認(rèn)的不推薦的改寫函數(shù)入口指令來實(shí)現(xiàn)的,一般只有在游戲外掛和金山詞霸之類的軟件才會用到這樣的掛鉤技術(shù),
而且金山詞霸經(jīng)常需要更新補(bǔ)丁解決不同系統(tǒng)兼容問題。

三、性能差別原因

如前面所述,tcmalloc確實(shí)用了很hacker的辦法來實(shí)現(xiàn)無縫的替換系統(tǒng)自帶的內(nèi)存分配函數(shù)(本人在使用這類技術(shù)通常是用來干壞事的。。。),但是這也不足以解釋為什么它的效率比我們自己的好那么多。
回到tcmalloc 的手冊,tcmalloc除了使用常規(guī)的小內(nèi)存管理外,對多線程環(huán)境做了特殊處理,這和我原來見到的內(nèi)存分配器大有不同,一般的內(nèi)存分配器作者都會偷懶,把多線程問題扔給使用者,大多是加
個bool型的模板參數(shù)來表示是否是多線程環(huán)境,還美其名曰:可定制,末了還得吹噓下模板的優(yōu)越性。
tcmalloc是怎么做的呢? 答案是每線程一個ThreadCache,大部分操作系統(tǒng)都會支持thread local storage 就是傳說中的TLS,這樣就可以實(shí)現(xiàn)每線程一個分配器了,
這樣,不同線程分配都是在各自的threadCache里分配的。我們的項(xiàng)目的分配器由于是多線程環(huán)境的,所以不管三七二十一,全都加鎖了,性能自然就低了。

僅僅是如此,還是不足以將tcmalloc和ptmalloc2分個高下,后者也是每個線程都有threadCache的。
關(guān)于這個問題,doc里有一段說明,原文貼出來:
ptmalloc2 also reduces lock contention by using per-thread arenas but there is a big problem with ptmalloc2's use of per-thread arenas. In ptmalloc2 memory can never move from one arena to another. This can lead to huge amounts of wasted space.
大意是這樣的:ptmalloc2 也是通過tls來降低線程鎖,但是ptmalloc2各個線程的內(nèi)存是獨(dú)立的,也就是說,第一個線程申請的內(nèi)存,釋放的時候還是必須放到第一個線程池中(不可移動),這樣可能導(dǎo)致大量內(nèi)存浪費(fèi)。
 

四、代碼細(xì)節(jié)

1、無縫替換malloc等crt和系統(tǒng)分配函數(shù)。

   前面提到tcmalloc會無縫的替換掉原有dll中的malloc,這就意味著使用tcmalloc的項(xiàng)目必須是 MD(多線程dll)或者M(jìn)Dd(多線程dll調(diào)試)。tcmalloc的dll定義了一個
static TCMallocGuard module_enter_exit_hook;
的靜態(tài)變量,這個變量會在dll加載的時候先于DllMain運(yùn)行,在這個類的構(gòu)造函數(shù),會運(yùn)行PatchWindowsFunctions來掛鉤所有dll的 malloc、free、new等分配函數(shù),這樣就達(dá)到了替換功能,除此之外,
為了保證系統(tǒng)兼容性,掛鉤API的時候還實(shí)現(xiàn)了智能分析指令,否則寫入第一條Jmp指令的時候可能會破環(huán)后續(xù)指令的完整性。

2、LibcInfoWithPatchFunctions 和ThreadCache。

LibcInfoWithPatchFunctions模板類包含tcmalloc實(shí)現(xiàn)的優(yōu)化后的malloc等一系列函數(shù)。LibcInfoWithPatchFunctions的模板參數(shù)在我看來沒什么用處,tcmalloc默認(rèn)可以掛鉤
最多10個帶有malloc導(dǎo)出函數(shù)的庫(我想肯定是夠用了)。ThreadCache在每個線程都會有一個TLS對象:
__thread ThreadCache* ThreadCache::threadlocal_heap_。

3、可能的問題


設(shè)想下這樣一個情景:假如有一個dll 在tcmalloc之前加載,并且在分配了內(nèi)存(使用crt提供的malloc),那么在加載tcmalloc后,tcmalloc會替換所有的free函數(shù),然后,在某個時刻,
在前面的那個dll代碼中釋放該內(nèi)存,這豈不是很危險。實(shí)際測試發(fā)現(xiàn)沒有任何問題,關(guān)鍵在這里:
 span = Static::pageheap()->GetDescriptor(p);
    if (!span) {
      // span can be NULL because the pointer passed in is invalid
      // (not something returned by malloc or friends), or because the
      // pointer was allocated with some other allocator besides
      // tcmalloc.  The latter can happen if tcmalloc is linked in via
      // a dynamic library, but is not listed last on the link line.
      // In that case, libraries after it on the link line will
      // allocate with libc malloc, but free with tcmalloc's free.
      (*invalid_free_fn)(ptr);  // Decide how to handle the bad free request
      return;
    }
tcmalloc會通過span識別這個內(nèi)存是否自己分配的,如果不是,tcmalloc會調(diào)用該dll原始對應(yīng)函數(shù)(這個很重要)釋放。這樣就解決了這個棘手的問題。

五、其他

其實(shí)tcmalloc使用的每個技術(shù)點(diǎn)我從前都用過,但是我從來沒想過用API掛鉤來實(shí)現(xiàn)這樣一個有趣的內(nèi)存優(yōu)化庫(即使想過,也是一閃而過就否定了)。
從tcmalloc得到靈感,結(jié)合常用的外掛技術(shù),可以很輕松的開發(fā)一個獨(dú)立工具:這個工具可以掛載到指定進(jìn)程進(jìn)行內(nèi)存優(yōu)化,在我看來,這可能可以作為一個外掛輔助工具來優(yōu)化那些
內(nèi)存優(yōu)化做的很差導(dǎo)致幀速很低的國產(chǎn)游戲。
posted on 2010-07-10 17:32 feixuwu 閱讀(10108) 評論(14)  編輯 收藏 引用 所屬分類: 游戲開發(fā)

FeedBack:
# re: 推薦一個跨平臺內(nèi)存分配器
2010-07-10 19:52 | chaogu
好像內(nèi)存分配策略沒有講明白.....
  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-07-10 20:39 | feixuwu
@chaogu
恩,這篇主要不是講常規(guī)小內(nèi)存分配的,那個到處都在講,沒啥新意了,文章資料里提到的很多都是常規(guī)小內(nèi)存實(shí)現(xiàn),也可以直接看代碼或者侯捷的STL源碼剖析,有詳細(xì)內(nèi)容的。  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-08-07 08:27 | maxime
小內(nèi)存分配器主要作用是“減小內(nèi)存碎片化趨勢,減小薄記內(nèi)存比例,提高小內(nèi)存利用率”,從性能上說,系統(tǒng)內(nèi)存分配器已針對小內(nèi)存分配進(jìn)行優(yōu)化,單純使用自定義的小內(nèi)存分配器,對性能幫助不會很大。內(nèi)置分配器意義還是體現(xiàn)在,實(shí)現(xiàn)無鎖分配,避免API調(diào)用切換開銷。
CRT自身new-delete會用到500個時鐘周期,而一個CS會消耗50個時鐘周期,一個mutex會用到2000個時鐘周期,以上是無競爭的情況。所以,如果用mutex做互斥,那還不如用系統(tǒng)的分配器;如果用CS,也不見會好多少,因?yàn)镃S會隨鎖競爭加劇大幅增加時間,甚至?xí)^mutex。
所以結(jié)論是,對于單線程,內(nèi)置分配器有一定的價值;對于多線程,帶鎖內(nèi)置分配器基本上可以無視了(至少對于winxp以后是這樣,win2k好像要打補(bǔ)丁)呵呵,從你說的情況來看,很有可能你們原來的分配器用mutex幫倒忙了。

tcmalloc中的唯一亮點(diǎn)應(yīng)該是,如何做到跨線程歸還內(nèi)存,又能保持高性能,猜想可能使用了某種二級分配策略,內(nèi)存塊可以屬于任何線程的內(nèi)存池,歸還到那個線程內(nèi)存池,就由這個內(nèi)存池管理。由于各個線程的分配和釋放多半不平衡,有線程池會撐滿,有的會不足。估計(jì)撐滿的就會歸還到公共內(nèi)存池。第一級分配無鎖,如果內(nèi)存池不足了,就進(jìn)入第二級帶鎖批量分配,而且第二級分配會先從公共內(nèi)存池獲取,如果還不夠,這才使用系統(tǒng)內(nèi)存分配,這該算是第三級分配了。


最后,tcmalloc也是可以用于MT版本的哦,詳見(要翻墻才能看見)http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-08-07 08:31 | maxime
為避免大家翻墻,將原文貼在下面了。另外,如果下載chrome的源代碼,其中就包含了tcmalloc的,它里面已經(jīng)幫你把這篇文章要做的都做了,用腳本的形式。

Hi,

I wanted to post a little information about some changes that I'm
working on finishing up for the windows version of tcmalloc. If
you've ever had trouble overriding malloc/free on windows, you might
find this useful.


With Chrome, we wanted to override the default C runtime allocators
with TCMalloc. Chrome links the C runtime statically (/MT) in
VS2005. Unfortunately, VS2005 does not have a static mechanism to
override all allocators. This sounds easy, but it is not - VS2005 and
VS2008 both use C runtimes with internal functions that cannot be
overridden. We also didn't like the runtime patching approach which
tcmalloc currently uses. So, to get static linkage to work, we take
the C runtime library from Microsoft and remove all heap allocators
from it using the LIB.EXE tool. We then implement stub functions for
the non-overridable functions in the C runtime and manually link
Chrome to use the new library.


If you want to do this too, here are the steps:


Steps
1) Create a slimmed down version of the C Runtime Library. The C
Runtime Library ships with VS2005 in $VCInstallDir\lib\libcmt.lib. We
use the script below to do this.
2) In TCMalloc's config.h, define WIN32_OVERRIDE_ALLOCATORS
3) Modify your DLL or EXE build with the following:
a) link in tcmalloc.lib by adding a Project Dependency to it.
b) in Properties -> Linker -> Input, set "Ignore Specific Library"
to "libcmt.lib"
c) in Properties -> Linker -> Input, add "mylibcmt.lib" to the
"Additional Dependencies" line.


SLIM_CRT.BAT
REM
REM This script takes libcmt.lib for VS2005 and removes the allocation
related
REM functions from it.
REM
REM Usage: prep_libcmt.bat <VCInstallDir> <OutputFile>
REM
REM VCInstallDir is the path where VC is installed, typically:
REM C:\Program Files\Microsoft Visual Studio 8\VC\
REM
REM OutputFile is the directory where the modified libcmt file should
be stored.
REM


SET LIBCMT=%1lib\libcmt.lib
SET LIBCMTPDB=%1lib\libcmt.pdb
SET OUTDIR=%2
SET OUTCMT=%2\libcmt.lib


MKDIR %OUTDIR%
COPY %LIBCMT% %OUTDIR%
COPY %LIBCMTPDB% %OUTDIR%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\malloc.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\free.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\realloc.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\calloc.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\new.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\delete.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\new2.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\delete2.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\align.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\msize.obj %OUTCMT%


LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapinit.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\expand.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapchk.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapwalk.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapmin.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\sbheap.obj %OUTCMT%
LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\smalheap.obj %OUTCMT%
  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-08-07 09:15 | feixuwu
@maxime
同意加鎖的自定義分配器還不如不用的說法(所以說設(shè)計(jì)討論在項(xiàng)目中是需要的,除了開發(fā)者,我們大家都不知道項(xiàng)目的多線程分配加鎖了:))。

對“系統(tǒng)內(nèi)存分配器已針對小內(nèi)存分配進(jìn)行優(yōu)化”,這個我觀點(diǎn)覺得有可能(畢竟沒有驗(yàn)證),不過我倒覺得crt分配小內(nèi)存的至少還是會有個head的,這個浪費(fèi)免不了了(當(dāng)然tcmalloc現(xiàn)在也是有頭的,一般自己實(shí)現(xiàn)的內(nèi)存分配器是不會有頭的),從比例上來說浪費(fèi)的還是比較多的,這個可以做個實(shí)驗(yàn)驗(yàn)證,一次分配50M和多次分配10byte至50M,2者進(jìn)程的內(nèi)存差距還是比較明顯的。
好在現(xiàn)在PC和服務(wù)器內(nèi)存越來越大,內(nèi)存分配器的主要焦點(diǎn)都集中在速度上了。

tcmalloc跨線程歸還內(nèi)存,確實(shí)是因?yàn)樗芯€程公用了底層的一個分配器,所以跨線程歸還是無需加鎖的(從手冊上看的,不知道博文提了沒有)。
關(guān)于tcmalloc亮點(diǎn),我倒覺得算法上的小優(yōu)化其實(shí)倒沒那么振奮,給我沖擊最大的是產(chǎn)品的可用性,以往一個產(chǎn)品要使用新的內(nèi)存分配器,一般需要改很多代碼,最常見的是將已有類從一個SmallObject之類的類繼承,很麻煩,這方面tcmalloc干的不錯。

最后感謝maxime提供了MT使用tcmalloc的資料,以我從前的看法,靜態(tài)編譯的版本是無法使用tcmalloc的。  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-08-08 11:19 | kingzt
不知道博主能否做出一個外掛式的內(nèi)存優(yōu)化工具分享一下,現(xiàn)在的國產(chǎn)游戲優(yōu)化確實(shí)是讓人無語,如果有這個的話情況估計(jì)會好很多  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-08-08 11:22 | kingzt
博主能否實(shí)現(xiàn)一個這樣的外掛式內(nèi)存優(yōu)化工具分享給國內(nèi)的游戲玩家,現(xiàn)在有的游戲優(yōu)化確實(shí)是讓人無語,如果有這個的話情況估計(jì)會好很多  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-09-15 01:08 | 求助啊
請問如何在MFC程序中使用此tcmalloc?
能說下嗎?
多謝了。
  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-09-17 21:03 | Roger
@求助啊
我在我的VS2003工程中用到TCMalloc,此功能有很多其他DLL模塊.
出現(xiàn)2個問題:
1。 有些DLL模塊在TCMall模塊之前加載,并且分配了內(nèi)存,此時不能被TCMalloc管理
2。 在進(jìn)程退出時異常崩潰
出現(xiàn)在:(*invalid_free_fn)(ptr)
好像是地址無效了.
我猜想是:hook其他dll模塊的函數(shù),而此時的dll模塊已經(jīng)卸載了,因此此指針函數(shù)無效.
// This lets you call back to a given function pointer if ptr is invalid.
// It is used primarily by windows code which wants a specialized callback.
inline void do_free_with_callback(void* ptr, void (*invalid_free_fn)(void*)) {
if (ptr == NULL) return;
ASSERT(Static::pageheap() != NULL); // Should not call free() before malloc()
const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
Span* span = NULL;
size_t cl = Static::pageheap()->GetSizeClassIfCached(p);

if (cl == 0) {
span = Static::pageheap()->GetDescriptor(p);
if (!span) {
// span can be NULL because the pointer passed in is invalid
// (not something returned by malloc or friends), or because the
// pointer was allocated with some other allocator besides
// tcmalloc. The latter can happen if tcmalloc is linked in via
// a dynamic library, but is not listed last on the link line.
// In that case, libraries after it on the link line will
// allocate with libc malloc, but free with tcmalloc's free.
(*invalid_free_fn)(ptr); // Decide how to handle the bad free request
return;
}  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2010-09-17 21:03 | Roger
我的QQ:roger201008@qq.com  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器[未登錄]
2011-08-25 22:12 | Lee
很奇怪,我在MFC工程里面把tcmalloc編譯進(jìn)去,vc居然報內(nèi)存泄漏。
我的環(huán)境是vc2010.
不知道可否有人碰到這個情況啊?  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2012-11-16 18:06 | gohay
大哥,tcmalloc 不是通過API掛鉤來實(shí)現(xiàn)無縫替換系統(tǒng)自帶的malloc等crt函數(shù)的。
tcmalloc是通過靜態(tài)全局變量的初始化早于main函數(shù)這個原理搞的,它定義了一個全局變量(tcmalloc.cc 文件中920行) static TCMallocGuard module_enter_exit_hook;
在TCMallocGuard這個類的構(gòu)造函數(shù)中做了一大堆事情用來替換系統(tǒng)自帶的malloc等crt函數(shù)  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2012-11-29 14:21 | feiwu
@gohay
抱歉我沒說清楚。
你說的那個是在tcmalooc在linux下的做法。在windows下就是改寫指令來處理的。
linux下不能掛鉤,但是可以先加載來覆蓋系統(tǒng)crtAPI,相比之下,linux下做這個更容易,linux甚至都不同編譯進(jìn)去就可以直接用。  回復(fù)  更多評論
  
# re: 推薦一個跨平臺內(nèi)存分配器
2013-05-17 22:02 | leehark
在windows下怎么做堆檢測呢?  回復(fù)  更多評論
  
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

文章轉(zhuǎn)載請注明出處

常用鏈接

留言簿(11)

隨筆分類

隨筆檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一级久久久| 91久久精品美女高潮| 亚洲免费影视| 亚洲欧美日韩在线综合| 国产一区视频观看| 欧美a级一区| 欧美精品精品一区| 亚洲伊人观看| 欧美一区二区久久久| 国内激情久久| 91久久精品日日躁夜夜躁欧美 | 久久精品一区二区三区四区| 久久激情视频免费观看| 亚洲人成绝费网站色www| 日韩午夜免费视频| 国产一区美女| 日韩视频在线观看免费| 国产日韩精品在线观看| 欧美激情精品久久久久久大尺度| 欧美日韩免费一区二区三区| 久久电影一区| 欧美激情亚洲另类| 久久久久国产精品www| 欧美女同在线视频| 久久午夜影视| 国产精品久久国产精品99gif| 久久露脸国产精品| 欧美日韩在线高清| 国产精品视频一区二区高潮| 女人色偷偷aa久久天堂| 国产精品vip| 亚洲电影在线播放| 国产伪娘ts一区| 99国产精品久久久久久久成人热| 激情自拍一区| 亚洲免费视频网站| 亚洲一区www| 欧美护士18xxxxhd| 美女视频黄 久久| 国产欧美日韩一区二区三区| 亚洲欧洲一区二区三区| 精品盗摄一区二区三区| 亚洲欧美激情精品一区二区| 一区二区精品在线| 免费视频一区| 欧美 日韩 国产一区二区在线视频 | 国产精品伦理| 亚洲精品在线观看视频| 亚洲欧洲另类| 免费看成人av| 欧美大片在线观看| 在线不卡a资源高清| 午夜久久一区| 欧美伊人久久久久久久久影院| 欧美日韩国产欧| 亚洲黄色影院| 亚洲毛片在线观看| 欧美国产精品专区| 亚洲人成网站精品片在线观看| 亚洲高清久久久| 久久久久久久999| 欧美1区2区3区| 亚洲第一福利在线观看| 久久偷看各类wc女厕嘘嘘偷窃| 久久野战av| 亚洲国产精品成人| 蜜臀久久99精品久久久久久9 | 9久草视频在线视频精品| 欧美电影美腿模特1979在线看| 欧美激情一区二区三区| 亚洲人妖在线| 欧美色偷偷大香| 亚洲免费视频中文字幕| 久久久噜久噜久久综合| 亚洲成色精品| 欧美国产丝袜视频| 在线中文字幕一区| 久久国产欧美日韩精品| 精品动漫一区| 欧美日本一区二区三区| 艳女tv在线观看国产一区| 午夜视频在线观看一区| 国产一区二区三区电影在线观看| 久久不射网站| 亚洲国产午夜| 午夜亚洲视频| 亚洲第一精品福利| 欧美日韩一区二区三区在线| 亚洲伊人一本大道中文字幕| 久久九九国产| 99成人在线| 国产亚洲美州欧州综合国| 亚洲国产成人在线| 亚洲欧美日韩区| 一区二区三区在线免费视频| 欧美电影免费观看高清| 亚洲欧美日韩综合aⅴ视频| 免费不卡在线观看av| 亚洲一区二区三区在线看| 国产一区二区三区av电影 | 免费日韩视频| 亚洲欧美伊人| 亚洲人成网在线播放| 久久久www成人免费精品| 一本色道久久加勒比精品| 国产欧美综合在线| 欧美日韩视频在线一区二区 | 欧美日韩大片| 久久精品国产99| 一区二区欧美日韩| 美女国产精品| 久久99在线观看| 亚洲图片欧洲图片av| 亚洲高清不卡在线观看| 国产日韩一区二区三区在线播放 | 欧美午夜精品久久久久久人妖| 久久久.com| 亚洲一区精彩视频| 亚洲美女av电影| 欧美成人三级在线| 久久三级福利| 久久激情五月丁香伊人| 亚洲欧美www| 一区二区三区视频免费在线观看 | 欧美日本韩国一区| 美日韩丰满少妇在线观看| 欧美在线一级va免费观看| 亚洲私人影院| 日韩亚洲欧美综合| 亚洲黄网站黄| 亚洲第一福利社区| 欧美成人免费全部| 欧美jizz19性欧美| 免费观看成人网| 美女主播一区| 麻豆91精品| 女女同性女同一区二区三区91| 久久婷婷色综合| 久久只精品国产| 乱人伦精品视频在线观看| 老牛影视一区二区三区| 久久综合免费视频影院| 美女视频黄a大片欧美| 免费观看亚洲视频大全| 欧美www视频| 亚洲丰满少妇videoshd| 91久久精品日日躁夜夜躁欧美| 亚洲成色999久久网站| 亚洲狠狠丁香婷婷综合久久久| 亚洲国产日韩欧美在线图片 | 久久久久久久久久久一区| 久久在线观看视频| 亚洲丰满在线| 一区二区日韩免费看| 亚洲资源在线观看| 欧美一区三区三区高中清蜜桃| 久久经典综合| 欧美激情视频免费观看| 欧美视频一区在线观看| 国产伦一区二区三区色一情| 久久影音先锋| 欧美日韩精品久久久| 国产精品国产福利国产秒拍| 国产亚洲午夜| 亚洲激情综合| 午夜激情一区| 欧美xx视频| 99精品欧美一区二区三区| 亚洲欧美日韩天堂| 久久久一区二区| 欧美三区免费完整视频在线观看| 国产欧美日本| 亚洲区第一页| 久久精品国产99国产精品| 欧美18av| 亚洲欧美日韩精品| 欧美成人情趣视频| 国产欧美日韩在线观看| 亚洲激情电影中文字幕| 欧美亚洲一级| 亚洲成人在线视频播放| 亚洲欧美成aⅴ人在线观看| 久久综合国产精品台湾中文娱乐网| 欧美日韩三级电影在线| 激情文学综合丁香| 亚洲性人人天天夜夜摸| 欧美成人a∨高清免费观看| 亚洲一区二区av电影| 欧美成人免费一级人片100| 国产网站欧美日韩免费精品在线观看| 亚洲精品日韩一| 蜜桃久久精品乱码一区二区| 中文国产成人精品| 欧美国产综合视频| 在线观看日韩精品| 久久精品欧美日韩精品| 亚洲手机成人高清视频| 欧美黄色小视频| 亚洲国产视频一区二区| 久久亚洲精品中文字幕冲田杏梨|