精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Web應用內存分析與內存泄漏定位

開發 開發工具
內存分析與內存泄漏定位是筆者現代 Web 開發工程化實踐之調試技巧的一部分,主要介紹 Web 開發中需要了解的內存分析與內存泄露定位手段,本部分涉及的參考資料統一聲明在Web 開發界面調試資料索引。

[[209282]]

內存分析與內存泄漏定位是筆者現代 Web 開發工程化實踐之調試技巧的一部分,主要介紹 Web 開發中需要了解的內存分析與內存泄露定位手段,本部分涉及的參考資料統一聲明在Web 開發界面調試資料索引。

無論是分布式計算系統、服務端應用程序還是 iOS、Android 原生應用都會存在內存泄漏問題,Web 應用自然也不可避免地存在著類似的問題。雖然因為網頁往往都是即用即走,較少地存在某個網頁長期運行的問題,即使存在內存泄漏可能表現地也不明顯;但是在某些數據展示型的,需要長期運行的頁面上,如果不及時解決內存泄漏可能會導致網頁占據過大地內存,不僅影響頁面性能,還可能導致整個系統的崩潰。前端每周清單推薦過的 How JavaScript works 就是非常不錯地介紹 JavaScript 運行機制的系列文章,其也對內存管理與內存泄漏有過分析,本文部分圖片與示例代碼即來自此系列。

類似于 C 這樣的語言提供了 malloc() 與 free() 這樣的底層內存管理原子操作,開發者需要顯式手動地進行內存的申請與釋放;而 Java 這樣的語言則是提供了自動化的內存回收機制,筆者在垃圾回收算法與 JVM 垃圾回收器綜述一文中有過介紹。JavaScript 也是采用的自動化內存回收機制,無論是 Object、String 等都是由垃圾回收進程自動回收處理。自動化內存回收并不意味著我們就可以忽略內存管理的相關操作,反而可能會導致更不易發現的內存泄漏出現。

內存分配與回收

筆者在 JavaScript Event Loop 機制詳解與 Vue.js 中實踐應用一文中介紹過 JavaScript 的內存模型,其主要也是由堆、棧、隊列三方面組成:

其中隊列指的是消息隊列、棧就是函數執行棧,其基本結構如下所示:

而主要的用戶創建的對象就存放在堆中,這也是我們內存分析與內存泄漏定位所需要關注的主要的區域。所謂內存,從硬件的角度來看,就是無數觸發器的組合;每個觸發器能夠存放 1 bit 位的數據,不同的觸發器由***的標識符定位,開發者可以根據該標識符讀寫該觸發器。抽象來看,我們可以將內存當做比特數組,而數據就是在內存中順序排布:

JavaScript 中開發者并不需要手動地為對象申請內存,只需要聲明變量,JavaScript Runtime 即可以自動地分配內存:

  1. var n = 374; // allocates memory for a number 
  2. var s = 'sessionstack'; // allocates memory for a string  
  3. var o = { 
  4.   a: 1, 
  5.   b: null 
  6. }; // allocates memory for an object and its contained values 
  7. var a = [1, null'str'];  // (like object) allocates memory for the 
  8.                            // array and its contained values 
  9. function f(a) { 
  10.   return a + 3; 
  11. } // allocates a function (which is a callable object) 
  12. // function expressions also allocate an object 
  13. someElement.addEventListener('click'function() { 
  14.   someElement.style.backgroundColor = 'blue'
  15. }, false); 

某個對象的內存生命周期分為了內存分配、內存使用與內存回收這三個步驟,當某個對象不再被需要時,它就應該被清除回收;所謂的垃圾回收器,Garbage Collector 即是負責追蹤內存分配情況、判斷某個被分配的內存是否有用,并且自動回收無用的內存。大部分的垃圾回收器是根據引用(Reference)來判斷某個對象是否存活,所謂的引用即是某個對象是否依賴于其他對象,如果存在依賴關系即存在引用;譬如某個 JavaScript 對象引用了它的原型對象。最簡單的垃圾回收算法即是引用計數(Reference Counting),即清除所有零引用的對象:

  1. var o1 = { 
  2.   o2: { 
  3.     x: 1 
  4.   } 
  5. }; 
  6. // 2 objects are created.  
  7. // 'o2' is referenced by 'o1' object as one of its properties. 
  8. // None can be garbage-collected 
  9.  
  10. var o3 = o1; // the 'o3' variable is the second thing that  
  11.             // has a reference to the object pointed by 'o1'.  
  12.                                                         
  13. o1 = 1;      // now, the object that was originally in 'o1' has a          
  14.             // single reference, embodied by the 'o3' variable 
  15.  
  16. var o4 = o3.o2; // reference to 'o2' property of the object. 
  17.                 // This object has now 2 references: one as 
  18.                 // a property.  
  19.                 // The other as the 'o4' variable 
  20.  
  21. o3 = '374'; // The object that was originally in 'o1' has now zero 
  22.             // references to it.  
  23.             // It can be garbage-collected. 
  24.             // However, what was its 'o2' property is still 
  25.             // referenced by the 'o4' variable, so it cannot be 
  26.             // freed. 
  27.  
  28. o4 = null; // what was the 'o2' property of the object originally in 
  29.            // 'o1' has zero references to it.  
  30.            // It can be garbage collected. 

不過這種算法往往受制于循環引用問題,即兩個無用的對象相互引用:

  1. function f() { 
  2.   var o1 = {}; 
  3.   var o2 = {}; 
  4.   o1.p = o2; // o1 references o2 
  5.   o2.p = o1; // o2 references o1. This creates a cycle. 
  6.  
  7. f(); 

稍為復雜的算法即是所謂的標記-清除(Mark-Sweep)算法,其根據某個對象是否可達來判斷某個對象是否可用。標記-清除算法會從某個根元素開始,譬如 window 對象開始,沿著引用樹向下遍歷,標記所有可達的對象為可用,并且清除其他未被標記的對象。

2012 年之后,幾乎所有的主流瀏覽器都實踐了基于標記-清除算法的垃圾回收器,并且各自也進行有針對性地優化。

內存泄漏

所謂的內存泄漏,即是指某個對象被無意間添加了某條引用,導致雖然實際上并不需要了,但還是能一直被遍歷可達,以致其內存始終無法回收。本部分我們簡要討論下 JavaScript 中常見的內存泄漏情境與處理方法。在新版本的 Chrome 中我們可以使用 Performance Monitor 來動態監測網頁性能的變化:

上圖中各項指標的含義為:

  • CPU usage - 當前站點的 CPU 使用量;
  • JS heap size - 應用的內存占用量;
  • DOM Nodes - 內存中 DOM 節點數目;
  • JS event listeners- 當前頁面上注冊的 JavaScript 時間監聽器數目;
  • Documents - 當前頁面中使用的樣式或者腳本文件數目;
  • Frames - 當前頁面上的 Frames 數目,包括 iframe 與 workers;
  • Layouts / sec - 每秒的 DOM 重布局數目;
  • Style recalcs / sec - 瀏覽器需要重新計算樣式的頻次;

當發現某個時間點可能存在內存泄漏時,我們可以使用 Memory 標簽頁將此時的堆分配情況打印下來:

 

 

 

全局變量

JavaScript 會將所有的為聲明的變量當做全局變量進行處理,即將其掛載到 global 對象上;瀏覽器中這里的 global 對象就是 window:

  1. function foo(arg) { 
  2.     bar = "some text"
  3.  
  4. // 等價于 
  5.  
  6. function foo(arg) { 
  7.     window.bar = "some text"

另一種常見的創建全局變量的方式就是誤用 this 指針:

  1. function foo() { 
  2.     this.var1 = "potential accidental global"
  3. // Foo called on its own, this points to the global object (window) 
  4. // rather than being undefined. 
  5. foo(); 

一旦某個變量被掛載到了 window 對象,就意味著它永遠是可達的。為了避免這種情況,我們應該盡可能地添加 use strict 或者進行模塊化編碼(參考 JavaScript 模塊演化簡史)。我們也可以擴展類似于下文的掃描函數,來檢測出 window 對象的非原生屬性,并加以判斷:

  1. function scan(o) { 
  2.   Object.keys(o).forEach(function(key) { 
  3.     var val = o[key]; 
  4.  
  5.     // Stop if object was created in another window 
  6.     if ( 
  7.       typeof val !== "string" && 
  8.       typeof val !== "number" && 
  9.       typeof val !== "boolean" && 
  10.       !(val instanceof Object) 
  11.     ) { 
  12.       debugger; 
  13.       console.log(key); 
  14.     } 
  15.  
  16.     // Traverse the nested object hierarchy 
  17.   }); 

定時器與閉包

我們經常會使用 setInterval 來執行定時任務,很多的框架也提供了基于回調的異步執行機制;這可能會導致回調中聲明了對于某個變量的依賴,譬如:

  1. var serverData = loadData(); 
  2. setInterval(function() { 
  3.     var renderer = document.getElementById('renderer'); 
  4.     if(renderer) { 
  5.         renderer.innerHTML = JSON.stringify(serverData); 
  6.     } 
  7. }, 5000); //This will be executed every ~5 seconds. 

定時器保有對于 serverData 變量的引用,如果我們不手動清除定時器話,那么該變量也就會一直可達,不被回收。而這里的 serverData 也是閉包形式被引入到 setInterval 的回調作用域中;閉包也是常見的可能導致內存泄漏的元兇之一:

  1. var theThing = null
  2. var replaceThing = function () { 
  3.   var originalThing = theThing; 
  4.   var unused = function () { 
  5.     if (originalThing) // a reference to 'originalThing' 
  6.       console.log("hi"); 
  7.   }; 
  8.   theThing = { 
  9.     longStr: new Array(1000000).join('*'), 
  10.     someMethod: function () { 
  11.       console.log("message"); 
  12.     } 
  13.   }; 
  14. }; 
  15. setInterval(replaceThing, 1000); 

上述代碼中 replaceThing 會定期執行,并且創建大的數組與 someMethod 閉包賦值給 theThing。someMethod 作用域是與 unused 共享的,unused 又有一個指向 originalThing 的引用。盡管 unused 并未被實際使用,theThing 的 someMethod 方法卻有可能會被外部使用,也就導致了 unused 始終處于可達狀態。unused 又會反向依賴于 theThing,最終導致大數組始終無法被清除。

DOM 引用與監聽器

有時候我們可能會將 DOM 元素存放到數據結構中,譬如當我們需要頻繁更新某個數據列表時,可能會將用到的數據列表存放在 JavaScript 數組中;這也就導致了每個 DOM 元素存在了兩個引用,分別在 DOM 樹與 JavaScript 數組中:

  1. var elements = { 
  2.     button: document.getElementById('button'), 
  3.     image: document.getElementById('image'
  4. }; 
  5. function doStuff() { 
  6.     elements.image.src = 'http://example.com/image_name.png'
  7. function removeImage() { 
  8.     // The image is a direct child of the body element. 
  9.     document.body.removeChild(document.getElementById('image')); 
  10.     // At this point, we still have a reference to #button in the 
  11.     //global elements object. In other words, the button element is 
  12.     //still in memory and cannot be collected by the GC. 

此時我們就需要將 DOM 樹與 JavaScript 數組中的引用皆刪除,才能真實地清除該對象。類似的,在老版本的瀏覽器中,如果我們清除某個 DOM 元素,我們需要首先移除其監聽器,否則瀏覽器并不會自動地幫我們清除該監聽器,或者回收該監聽器引用的對象:

  1. var element = document.getElementById('launch-button'); 
  2. var counter = 0; 
  3. function onClick(event) { 
  4.    counter++; 
  5.    element.innerHtml = 'text ' + counter; 
  6. element.addEventListener('click', onClick); 
  7. // Do stuff 
  8. element.removeEventListener('click', onClick); 
  9. element.parentNode.removeChild(element); 
  10. // Now when element goes out of scope, 
  11. // both element and onClick will be collected even in old browsers // that don't handle cycles well. 

現代瀏覽器使用的現代垃圾回收器則會幫我們自動地檢測這種循環依賴,并且予以清除;jQuery 等第三方庫也會在清除元素之前首先移除其監聽事件。

iframe

iframe 是常見的界面共享方式,不過如果我們在父界面或者子界面中添加了對于父界面某對象的引用,譬如:

  1. // 子頁面內 
  2. window.top.innerObject = someInsideObject 
  3. window.top.document.addEventLister(‘click’, function() { … }); 
  4.  
  5. // 外部頁面 
  6.  innerObject = iframeEl.contentWindow.someInsideObject 

就有可能導致 iframe 卸載(移除元素)之后仍然有部分對象保留下來,我們可以在移除 iframe 之前執行強制的頁面重載:

  1. <a href="#">Remove</a> 
  2. <iframe src="url" /> 
  3.  
  4. $('a').click(function(){ 
  5.     $('iframe')[0].contentWindow.location.reload(); 
  6.     // 線上環境實測重置 src 效果會更好 
  7.     // $('iframe')[0].src = "javascript:false"
  8.     setTimeout(function(){ 
  9.        $('iframe').remove(); 
  10.     }, 1000); 
  11. }); 

或者手動地執行頁面清除操作:

  1. window.onbeforeunload = function(){ 
  2.     $(document).unbind().die();    //remove listeners on document 
  3.     $(document).find('*').unbind().die(); //remove listeners on all nodes 
  4.     //clean up cookies 
  5.     /remove items from localStorage 

Web Worker

現代瀏覽器中我們經常使用 Web Worker 來運行后臺任務,不過有時候如果我們過于頻繁且不加容錯地在主線程與工作線程之間傳遞數據,可能會導致內存泄漏:

  1. function send() { 
  2.  setInterval(function() {  
  3.     const data = { 
  4.      array1: get100Arrays(), 
  5.      array2: get500Arrays() 
  6.     }; 
  7.  
  8.     let json = JSON.stringify( data ); 
  9.     let arbfr = str2ab (json); 
  10.     worker.postMessage(arbfr, [arbfr]); 
  11.   }, 10); 
  12.  
  13.  
  14. function str2ab(str) { 
  15.    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char 
  16.    var bufView = new Uint16Array(buf); 
  17.    for (var i=0, strLen=str.length; i<strLen; i++) { 
  18.      bufView[i] = str.charCodeAt(i); 
  19.    } 
  20.    return buf; 
  21.  } 

在實際的代碼中我們應該檢測 Transferable Objects 是否正常工作:

  1. let ab = new ArrayBuffer(1); 
  2.  
  3. try { 
  4.    worker.postMessage(ab, [ab]); 
  5.  
  6.    if (ab.byteLength) { 
  7.       console.log('TRANSFERABLE OBJECTS are not supported in your browser!'); 
  8.    }  
  9.    else { 
  10.      console.log('USING TRANSFERABLE OBJECTS'); 
  11.    } 
  12. }  
  13. catch(e) { 
  14.   console.log('TRANSFERABLE OBJECTS are not supported in your browser!'); 
  15. }  

 【本文是51CTO專欄作者“張梓雄 ”的原創文章,如需轉載請通過51CTO與作者聯系】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2016-12-05 16:33:30

2024-03-11 08:22:40

Java內存泄漏

2015-03-30 11:18:50

內存管理Android

2022-09-09 15:58:29

HiveServerHive 組件Java 開發

2012-08-13 10:14:36

IBMdW

2021-08-19 09:50:53

Java內存泄漏

2009-06-10 22:03:40

JavaScript內IE內存泄漏

2017-03-20 13:43:51

Node.js內存泄漏

2017-03-19 16:40:28

漏洞Node.js內存泄漏

2018-10-25 15:24:10

ThreadLocal內存泄漏Java

2023-12-18 10:45:23

內存泄漏計算機服務器

2012-02-22 21:28:58

內存泄漏

2010-10-25 10:10:27

ibmdwJava

2025-05-06 07:24:24

2021-06-03 21:13:03

內存Python管理

2020-01-03 16:04:10

Node.js內存泄漏

2021-08-09 09:54:37

內存泄漏JS 阿里云

2021-08-05 15:28:22

JS內存泄漏

2019-01-30 18:24:14

Java內存泄漏編程語言

2020-06-08 09:18:59

JavaScript開發技術
點贊
收藏

51CTO技術棧公眾號

毛片一区二区三区四区| 日韩免费在线免费观看| 杨幂一区二区国产精品| 男女羞羞在线观看| 中文字幕精品在线不卡| 产国精品偷在线| www.com亚洲| 综合日韩在线| 国产亚洲欧美一区| 午夜影院福利社| 日韩中文视频| 性欧美疯狂xxxxbbbb| 亚洲一区二区三区精品动漫| 亚洲av无码一区二区三区性色 | 欧美xxxx做受欧美护士| 亚洲女同ⅹxx女同tv| 久久亚洲免费| www.麻豆av| 蜜桃久久精品一区二区| 57pao成人国产永久免费| 日韩在线一卡二卡| 国产99亚洲| 精品福利在线导航| 中文字幕色网站| 不卡一二三区| 亚洲va国产天堂va久久en| 国产奶头好大揉着好爽视频| 你懂的视频在线| 成人污视频在线观看| 国产日韩欧美中文| 成人黄色片在线观看| 亚洲专区一区| 午夜精品蜜臀一区二区三区免费| 午夜免费激情视频| 91精品天堂福利在线观看 | 中文字幕中文字幕在线中高清免费版| 久久精品日产第一区二区三区高清版| 极品校花啪啪激情久久| 午夜老司机福利| 狠狠色狠狠色综合日日91app| 国产精品福利网站| 国产一级一级国产| 久久久久国产一区二区| 91av成人在线| 亚洲精品自产拍| 亚洲级视频在线观看免费1级| 天天综合国产| 在线视频你懂得| 日韩激情在线视频| 亚洲成人av电影在线| 国产精品国产亚洲精品看不卡15| 亚洲色图综合区| 日本中文字幕视频在线| 91视频观看视频| 狠狠色综合网站久久久久久久| 亚洲a视频在线| 国产伦精品一区二区三区免费| 91精品在线影院| 91女人18毛片水多国产| 国产真实乱对白精彩久久| 国产欧美久久一区二区| 91国内精品视频| 国内精品写真在线观看| 91超碰在线电影| 亚洲第一页在线观看| 高清国产一区二区| 国产区二精品视| 亚洲aaa在线观看| 国产亚洲综合在线| av动漫免费观看| 51xtv成人影院| 亚洲一级二级在线| 免费午夜视频在线观看| 福利一区和二区| 欧美一区二区三区免费大片 | 日本视频一区二区在线观看| porn视频在线观看| 亚洲天堂久久久久久久| 国产成人永久免费视频| 色综合亚洲图丝熟| 欧美亚洲综合色| 免费看91视频| 免费av一区二区三区四区| 中文字幕国产精品| 日韩aⅴ视频一区二区三区| 亚洲 欧美 日韩在线| 色婷婷av一区二区三区丝袜美腿| 一个色综合导航| 欧美色图一区二区| 国产免费成人| 成人久久精品视频| 蜜桃久久一区二区三区| 欧美国产综合一区二区| 韩国无码av片在线观看网站| 夜鲁夜鲁夜鲁视频在线播放| 欧美日韩国产色站一区二区三区| 亚洲成人精品在线播放| 亚洲免费福利一区| 久久久久999| 国产综合精品视频| 国产在线精品不卡| 欧美日韩综合另类| 黑人另类精品××××性爽| 欧洲亚洲国产日韩| 中国特级黄色大片| 欧美大片aaaa| 欧亚精品中文字幕| 性做久久久久久久| 中文字幕一区二区三区四区不卡 | 爽好久久久欧美精品| 91精品国产高清久久久久久91裸体| 先锋av资源站| 一区二区三区影院| 视频二区在线播放| 伊人久久大香线蕉综合网蜜芽| 欧美成人免费全部| 亚洲天堂网在线观看视频| 99久久国产免费看| 成人av在线不卡| 99久久99九九99九九九| 亚洲天堂av综合网| 日本午夜视频在线观看| 丁香五精品蜜臀久久久久99网站| 亚洲三区四区| h1515四虎成人| 亚洲欧美日韩国产成人| 日韩和一区二区| 国产成人精品1024| 9l视频自拍9l视频自拍| 国产精品亲子伦av一区二区三区| 精品亚洲aⅴ在线观看| 伊人国产在线观看| 国产精品538一区二区在线| 一区不卡视频| 欧美美女福利视频| 日韩性xxxx爱| 中文字幕乱码人妻二区三区| 国产日韩综合av| 日韩欧美一区二| 欧美日韩另类图片| 午夜精品www| 天天操天天干天天操| 亚洲国产综合人成综合网站| 亚洲丝袜在线观看| 午夜视频一区| 97夜夜澡人人双人人人喊| gogo在线高清视频| 日韩欧美综合在线| 国产一级理论片| av成人免费在线观看| 黄页网站大全在线观看| 欧美男人操女人视频| 日本在线精品视频| 国产福利电影在线| 欧美性大战久久久久久久蜜臀| 精品欧美一区二区久久久| 日韩高清一区二区| 一区二区三区的久久的视频| 日韩专区视频网站| 久久影院资源网| 亚洲女人18毛片水真多| 亚洲aⅴ怡春院| 欧美老熟妇乱大交xxxxx| 三级欧美韩日大片在线看| 日本一区二区视频| 欧美一级片免费看| 久久综合狠狠综合久久激情| 捆绑调教一区二区三区| 日韩美女中文字幕| 户外极限露出调教在线视频| 一本一道波多野结衣一区二区| 精品久久久久久中文字幕人妻最新| 久久福利影视| 一区二区三区视频在线播放| 97色婷婷成人综合在线观看| 久久久久成人精品| 男人天堂亚洲二区| 欧美日本乱大交xxxxx| 欧美日韩精品在线观看视频| 99热国产精品| 性chinese极品按摩| 一区二区三区四区日韩| 国产一区二区视频在线免费观看 | 国产成人免费看一级大黄| 亚洲午夜三级在线| 中字幕一区二区三区乱码| 国产精品亚洲专一区二区三区| 毛片在线视频播放| 日韩毛片视频| 国产在线精品一区| 精品福利在线| 国内精品小视频| 成人jjav| 亚洲а∨天堂久久精品9966| 中文字幕在线日本| 一区二区三区在线视频观看 | av污在线观看| 今天的高清视频免费播放成人| 日本视频一区二区在线观看| 婷婷综合国产| 国产精品在线看| 亚洲女同志freevdieo| 久久九九国产精品怡红院 | 黄页免费在线观看视频| 91亚洲国产高清| 欧美一区亚洲二区| 在线日韩成人| 成人乱色短篇合集| 欧美成人a交片免费看| 色综合色综合久久综合频道88| a视频网址在线观看| 亚洲精品二三区| 精品毛片一区二区三区| 91国偷自产一区二区三区观看| 国产 日韩 欧美 成人| 亚洲婷婷在线视频| 69xxx免费| 久久久久99精品国产片| 黄色国产在线视频| 国产一区二区福利视频| 国产精品久久久毛片| 午夜在线精品偷拍| 蜜臀av色欲a片无码精品一区 | 91成人入口| 亚洲精品免费网站| 日韩色性视频| 国产免费一区视频观看免费| 波多视频一区| 欧美亚洲激情在线| 丰满诱人av在线播放| 欧美成人性生活| av在线免费网址| 久久影视免费观看 | 亚洲欧美日韩国产另类专区| 天天操天天舔天天射| 久久久精品日韩欧美| 欧美熟妇精品黑人巨大一二三区| 丁香另类激情小说| 日韩黄色一区二区| 成人性色生活片免费看爆迷你毛片| 国产5g成人5g天天爽| 韩日av一区二区| 在线视频观看一区二区| 久久99深爱久久99精品| 五月天视频在线观看| 韩国一区二区三区| 亚洲免费黄色录像| 国产一区二区三区四区在线观看| 久久6免费视频| 国产裸体歌舞团一区二区| 久久久久亚洲av无码麻豆| 国产精品18久久久久久久久久久久| 亚洲午夜激情影院| 国产麻豆精品在线| 国产日韩视频一区| 91捆绑美女网站| av网在线播放| 国产精品久久久久aaaa樱花| 亚洲一级理论片| 亚洲欧美日韩一区二区三区在线观看| 欧美在线视频第一页| 悠悠色在线精品| 日韩欧美不卡视频| 日本道在线观看一区二区| 中文无码精品一区二区三区| 欧美猛男男办公室激情| 国产极品久久久| 日韩久久精品电影| 成人影视在线播放| 久久国产精品久久久久久| 日本不卡影院| 日韩av免费在线| 欧洲午夜精品| 国产精选一区二区| jiujiure精品视频播放| 欧美大片免费播放| 一本久道综合久久精品| 色片在线免费观看| 粉嫩av亚洲一区二区图片| 日韩一级视频在线观看| 中文字幕国产一区二区| 久久艹精品视频| 欧美性猛交xxxx免费看漫画| 91麻豆一区二区| 亚洲国语精品自产拍在线观看| 国产黄色片在线观看| 九九综合九九综合| 欧美成人黑人| 91在线短视频| 国产日产精品一区二区三区四区的观看方式| 一区在线电影| 国产日产高清欧美一区二区三区| www.99在线| 成人国产精品免费观看| 亚洲一级理论片| 精品久久久久国产| 国产老女人乱淫免费| 日韩高清av一区二区三区| 成年人视频在线看| 久久男人av资源网站| 欧美大片高清| 深夜福利日韩在线看| 一区二区视频在线播放| 亚洲欧美卡通动漫| 香蕉久久aⅴ一区二区三区| 国产欧美日韩在线一区二区| 久久欧美中文字幕| 中国china体内裑精亚洲片| 亚洲免费精品视频| 国产成人久久精品77777综合| 青青草成人在线观看| 成人在线看视频| 国产激情视频一区二区三区欧美 | av在线一区不卡| 国产精品一区二区av| 国产精品久久久久久| 成人小视频在线看| 成人美女视频在线观看| 黄色录像一级片| 欧美视频第二页| 日韩精品视频无播放器在线看| 欧美成人免费大片| 黄色网址在线免费播放| 亚洲成人资源| 欧美精品自拍偷拍| 日本一区二区三区精品视频| 永久免费毛片在线观看| 成人av观看| 国产精品一区二区视频| 一区二区欧美日韩视频| 爱爱免费小视频| 久久97视频| 日韩精品电影网站| 销魂美女一区二区三区视频在线| 91精品又粗又猛又爽| 亚洲欧美视频一区| 国产乱码久久久久| 精品国偷自产在线视频| 青青在线精品| 亚洲欧洲国产日韩精品| 青青草精品视频| 91禁男男在线观看| 欧美日韩精品一区二区| 三区四区在线视频| 91精品国产综合久久香蕉| 久久国产成人精品| 超碰人人草人人| 欧美丰满少妇人妻精品| 欧美日韩午夜视频在线观看| 五月激情丁香婷婷| 2021国产精品视频| 日韩mv欧美mv国产网站| 久久美女福利视频| 久久精品一区蜜桃臀影院| 凹凸精品一区二区三区| 中文字幕九色91在线| av在线亚洲一区| 国产精品一区在线免费观看| 国产成人精品亚洲日本在线桃色| 欧美日韩大片在线观看| 亚洲国产精品久久精品怡红院| 福利影院在线看| 奇米影视首页 狠狠色丁香婷婷久久综合| 亚洲欧美日韩专区| 国产福利在线导航| 欧美一区二区三区播放老司机| 男人添女人下部高潮视频在线观看| 99久久精品无码一区二区毛片 | 成人动漫中文字幕| yjizz国产| 日韩性生活视频| 福利片一区二区| 国产一级特黄a大片免费| 亚洲天堂网中文字| 无码精品一区二区三区在线| 国产精品久久久久久久久久小说 | 国产精品极品在线观看| 青青草原av在线播放| 国产精品女人毛片| 国产黄色av网站| 青青青国产精品一区二区| 色欧美自拍视频| 蜜臀视频在线观看| 91传媒视频在线播放| 国产秀色在线www免费观看| 精品久久久久久一区| 青草国产精品久久久久久| 久久精品性爱视频| 一个人www欧美| 国产精品xxx在线观看| 国产高潮免费视频| 亚洲第一福利一区| 精品51国产黑色丝袜高跟鞋| 精品一区二区国产| 久国产精品韩国三级视频| 日本三级视频在线| 日韩在线小视频| 天堂俺去俺来也www久久婷婷| 久久成年人网站| 欧美性生活大片免费观看网址|