◆寄存器:我們在程序中無法控制◆棧:存放基本類型的數據和對象的引用,但對象本身不存放在棧中,而是存放在堆中◆堆:存放用new產生的數據◆靜態域:存放在對象中用static定義的靜態成員◆常量池:存放常量◆非RAM存儲:硬盤等永久存儲空間1.java是如何管理內存的Java的內存管理就是對象的分配和釋放問題。(兩部分)分配:內存的分配是由程序完成的,程序員需要通過關鍵字new為每個對象申請內存空間(基本類型除外),所有" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

JAVA 內存管理總結

系統 1877 0


JAVA 內存管理總結
?

<!--StartFragment -->
?

◆寄存器:我們在程序中無法控制

◆棧:存放基本類型的數據和對象的引用,但對象本身不存放在棧中,而是存放在堆中

◆堆:存放用new產生的數據

◆靜態域:存放在對象中用static定義的靜態成員

◆常量池:存放常量

◆非RAM存儲:硬盤等永久存儲空間

1. java 是如何管理內存的

?Java 的內存管理就是對象的分配和釋放問題。(兩部分)??

分配 :內存的分配是由程序完成的,程序員需要通過關鍵字 new 為每個對象申請內存空間 ( 基本類型除外 ) ,所有的對象都在堆 (Heap) 中分配空間。
釋放 :對象的釋放是由垃圾回收機制決定和執行的,這樣做確實簡化了程序員的工作。但同時,它也加重了 JVM 的工作。因為, GC 為了能夠正確釋放對象, GC 必須監控每一個對象的運行狀態,包括對象的申請、引用、被引用、賦值等, GC 都需要進行監控。??

2.? 什么叫 java 的內存泄露

????? 在 Java 中,內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點,首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連(也就是說仍存在該內存對象的引用);其次,這些對象是無用的,即程序以后不會再使用這些對象。如果對象滿足這兩個條件,這些對象就可以判定為 Java 中的內存泄漏,這些對象不會被 GC 所回收,然而它卻占用內存。

3. JVM 的內存區域組成

java 把內存分兩種:一種是棧內存,另一種是堆內存 1 。在函數中定義的基本類型變量和對象的引用變量都在函數的棧內存中分配; 2 。堆內存用來存放由 new 創建的對象和數組以及對象的實例變量 在函數(代碼塊)中定義一個變量時, java 就在棧中為這個變量分配內存空間,當超過變量的作用域后, java 會自動釋放掉為該變量所分配的內存空間;在堆中分配的內存由 java 虛擬機的自動垃圾回收器來管理
堆和棧的優缺點????

? 堆的優勢是可以動態分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配內存的。

缺點就是要在運行時動態分配內存,存取速度較慢; 棧的優勢是,存取速度比堆要快,僅次于直接位于 CPU 中的寄存器。

另外,棧數據可以共享。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。

4. Java 中數據在內存中是如何存儲的

a)? 基本數據類型

?? Java 的基本數據類型共有 8 種,即 int, short, long, byte, float, double, boolean, char ( 注意,并沒有 string 的基本類型 ) 。這種類型的定義是通過諸如 int a = 3 ; long b = 255L ;的形式來定義的。如 int a = 3 ;這里的 a 是一個指向 int 類型的引用,指向 3 這個字面值。這些字面值的數據,由于大小可知,生存期可知 ( 這些字面值定義在某個程序塊里面,程序塊退出后,字段值就消失了 ) ,出于追求速度的原因,就存在于棧中。
另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。比如:我們同時定義:
int a=3;
int b =3;
???? 編譯器先處理 int a = 3 ;首先它會在棧中創建一個變量為 a 的引用,然后查找有沒有字面值為 3 的地址,沒找到,就開辟一個存放 3 這個字面值的地址,然后將 a 指向 3 的地址。接著處理 int b = 3 ;在創建完 b 這個引用變量后,由于在棧中已經有 3 這個字面值,便將 b 直接指向 3 的地址。這樣,就出現了 a 與 b 同時均指向 3 的情況。????? 定義完 a 與 b 的值后,再令 a = 4 ;那么, b 不會等于 4 ,還是等于 3 。在編譯器內部,遇到時,它就會重新搜索棧中是否有 4 的字面值,如果沒有,重新開辟地址存放 4 的值;如果已經有了,則直接將 a 指向這個地址。因此 a 值的改變不會影響到 b 的值。

b)??? 對象

在 Java 中,創建一個對象包括對象的聲明和實例化兩步,下面用一個例題來說明對象的內存模型。  假設有類 Rectangle 定義如下:
public class Rectangle {
double width ;
double height ;
public Rectangle( double w, double h){
w = width ;
h = height ;
}
}
(1) 聲明對象時的內存模型
 用 Rectangle rect ;聲明一個對象 rect 時,將在棧內存為對象的引用變量 rect 分配內存空間,但 Rectangle 的值為空,稱 rect 是一個空對象。空對象不能使用,因為它還沒有引用任何 " 實體 " 。
(2) 對象實例化時的內存模型
 當執行 rect=new Rectangle(3,5) ;時,會做兩件事: 在堆內存中為類的成員變量 width,height 分配內存,并將其初始化為各數據類型的默認值;接著進行顯式初始化(類定義時的初始化值);最后調用構造方法,為成員變量賦值。??? 返回堆內存中對象的引用(相當于首地址)給引用變量 rect, 以后就可以通過 rect 來引用堆內存中的對象了。

c)??? 創建多個不同的對象實例

??????? 一個類通過使用 new 運算符可以創建多個不同的對象實例,這些對象實例將在堆中被分配不同的內存空間,改變其中一個對象的狀態不會影響其他對象的狀態。例如:
Rectangle r1= new? Rectangle( 3 , 5 );
Rectangle r2= new? Rectangle( 4 , 6 );
 此時,將在堆內存中分別為兩個對象的成員變量 width 、 height 分配內存空間,兩個對象在堆內存中占據的空間是互不相同的。如果有:
Rectangle r1= new? Rectangle( 3 , 5 );
Rectangle r2=r1;
則在堆內存中只創建了一個對象實例,在棧內存中創建了兩個對象引用,兩個對象引用同時指向一個對象實例。
?

d)??? 包裝類

???????? 基本類型都有對應的包裝類:如 int 對應 Integer 類, double 對應 Double 類等,基本類型的定義都是直接在棧中,如果用包裝類來創建對象,就和普通對象一樣了。例如: int i=0 ; i 直接存儲在棧中。?? Integer i ( i 此時是對象) = new Integer(5) ;這樣, i 對象數據存儲在堆中, i 的引用存儲在棧中,通過棧中的引用來操作對象。
?

e)??? String

? String 是一個特殊的包裝類數據。可以用以下兩種方式創建: String str = new String("abc") ; String str = "abc";
第一種創建方式,和普通對象的的創建過程一樣;
第二種創建方式, Java 內部將此語句轉化為以下幾個步驟:
(1) 先定義一個名為 str 的對 String 類的對象引用變量: String str ;
(2) 在棧中查找有沒有存放值為 "abc" 的地址,如果沒有,則開辟一個存放字面值為 "abc"
地址,接著創建一個新的 String 類的對象 o ,并將 o 的字符串值指向這個地址,而且在棧
這個地址旁邊記下這個引用的對象 o 。如果已經有了值為 "abc" 的地址,則查找對象 o ,并
回 o 的地址。
(3) 將 str 指向對象 o 的地址。
值得注意的是,一般 String 類中字符串值都是直接存值的。但像 String str = "abc" ;這種
合下,其字符串值卻是保存了一個指向存在棧中數據的引用。
為了更好地說明這個問題,我們可以通過以下的幾個代碼進行驗證。
String str1="abc" ;
String str2="abc" ;
System .out.println(s1==s2) ; //true
注意,這里并不用 str1.equals(str2) ;的方式,因為這將比較兩個字符串的值是否相等。 == 號,根據 JDK 的說明,只有在兩個引用都指向了同一個對象時才返回真值。而我們在這里要看的是, str1 與 str2 是否都指向了同一個對象。
我們再接著看以下的代碼。
String str1= new String( "abc" ) ;
String str2= "abc" ;
System .out.println(str1==str2) ; //false
創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。  ??? 以上兩段代碼說明,只要是用 new() 來新建對象的,都會在堆中創建,而且其字符串是單獨存值的,即使與棧中的數據相同,也不會與棧中的數據共享。

f)??? 數組

???????? 當定義一個數組, int x[] ;或 int []x ;時,在棧內存中創建一個數組引用,通過該引用(即數組名)來引用數組。 x=new int[3] ;將在堆內存中分配 3 個保存 int 型數據的空間,堆內存的首地址放到棧內存中,每個數組元素被初始化為 0 。
?

g)??? 靜態變量

???????? 用 static 的修飾的變量和方法,實際上是指定了這些變量和方法在內存中的 " 固定位置 " - static storage ,可以理解為所有實例對象共有的內存空間。 static 變量有點類似于 C 中的全局變量的概念;靜態表示的是內存的共享,就是它的每一個實例都指向同一個內存地址。把 static 拿來,就是告訴 JVM 它是靜態的,它的引用(含間接引用)都是指向同一個位置,在那個地方,你把它改了,它就不會變成原樣,你把它清理了,它就不會回來了。????????? 那靜態變量與方法是在什么時候初始化的呢?對于兩種不同的類屬性, static 屬性與 instance 屬性,初始化的時機是不同的。 instance 屬性在創建實例的時候初始化, static 屬性在類加載,也就是第一次用到這個類的時候初始化,對于后來的實例的創建,不再次進行初始化。????????? 我們常可看到類似以下的例子來說明這個問題:
class Student{
static int numberOfStudents =0;
Student()
{
numberOfStudents ++;
}
}
每一次創建一個新的 Student 實例時 , 成員 numberOfStudents 都會不斷的遞增 , 并且所有的 Student 實例都訪問同一個 numberOfStudents 變量 , 實際上 int numberOfStudents 變量在內存中只存儲在一個位置上。

5. Java 的內存管理實例

? Java 程序的多個部分 ( 方法,變量,對象 ) 駐留在內存中以下兩個位置:即堆和棧,現在我們只關心 3 類事物:實例變量,局部變量和對象:
實例變量和對象駐留在堆上
局部變量駐留在棧上
?????? 讓我們查看一個 java 程序,看看他的各部分如何創建并且映射到棧和堆中:
public class Dog {
Collar c;
String name ;
//1. main() 方法位于棧上
public static void main(String[] args) {
//2. 在棧上創建引用變量 d, 但 Dog 對象尚未存在
Dog d;
//3. 創建新的 Dog 對象,并將其賦予 d 引用變量
d = new Dog();
//4. 將引用變量的一個副本傳遞給 go() 方法
d.go(d);
}
//5. 將 go() 方法置于棧上,并將 dog 參數作為局部變量
void go(Dog dog){
//6. 在堆上創建新的 Collar 對象,并將其賦予 Dog 的實例變量
c = new Collar();
}
//7. 將 setName() 添加到棧上,并將 dogName 參數作為其局部變量
void setName(String dogName){
//8. name 的實例對象也引用 String 對象
name =dogName;
}
//9. 程序執行完成后, setName() 將會完成并從棧中清除,此時,局部變量 dogName 也會消失,盡管它所引用的 String 仍在堆上
}

6. 垃圾回收機制:

(問題一:什么叫垃圾回收機制?) 垃圾回收是一種動態存儲管理技術,它自動地釋放不再被程序引用的對象,按照特定的垃圾收集算法來實現資源自動回收的功能。當一個對象不再被引用的時候,內存回收它占領的空間,以便空間被后來的新對象使用,以免造成內存泄露。 (問題二: java 的垃圾回收有什么特點?) JAVA 語言不允許程序員直接控制內存空間的使用。內存空間的分配和回收都是由 JRE 負責在后臺自動進行的,尤其是無用內存空間的回收操作 (garbagecollection, 也稱垃圾回收 ) ,只能由運行環境提供的一個超級線程進行監測和控制。 (問題三:垃圾回收器什么時候會運行?) 一般是在 CPU 空閑或空間不足時自動進行垃圾回收,而程序員無法精確控制垃圾回收的時機和順序等。 (問題四:什么樣的對象符合垃圾回收條件?) 當沒有任何獲得線程能訪問一個對象時,該對象就符合垃圾回收條件。 (問題五:垃圾回收器是怎樣工作的?) 垃圾回收器如發現一個對象不能被任何活線程訪問時,他將認為該對象符合刪除條件,就將其加入回收隊列,但不是立即銷毀對象,何時銷毀并釋放內存是無法預知的。垃圾回收不能強制執行,然而 Java 提供了一些方法(如: System.gc() 方法),允許你請求 JVM 執行垃圾回收,而不是要求,虛擬機會盡其所能滿足請求,但是不能保證 JVM 從內存中刪除所有不用的對象。 (問題六:一個 java 程序能夠耗盡內存嗎?) 可以。垃圾收集系統嘗試在對象不被使用時把他們從內存中刪除。然而,如果保持太多活的對象,系統則可能會耗盡內存。垃圾回收器不能保證有足夠的內存,只能保證可用內存盡可能的得到高效的管理。 (問題七:如何顯示的使對象符合垃圾回收條件?) ( 1 ) 空引用 :當對象沒有對他可到達引用時,他就符合垃圾回收的條件。也就是說如果沒有對他的引用,刪除對象的引用就可以達到目的,因此我們可以把引用變量設置為 null ,來符合垃圾回收的條件。
StringBuffer sb = new StringBuffer( "hello" );
System.out.println(sb);
sb= null ;
( 2 ) 重新為引用變量賦值:可以通過設置引用變量引用另一個對象來解除該引用變量與一個對象間的引用關系。
StringBuffer sb1 = new StringBuffer( "hello" );
StringBuffer sb2 = new StringBuffer( "goodbye" );
System.out.println(sb1);
sb1=sb2; // 此時 "hello" 符合回收條件??
( 3 ) 方法內創建的對象:所創建的局部變量僅在該方法的作用期間內存在。一旦該方法返回,在這個方法內創建的對象就符合垃圾收集條件。有一種明顯的例外情況,就是方法的返回對象。
public static void main(String[] args) {
Date d = getDate();
System. out .println( "d = " + d);
}
private static Date getDate() {
Date d2 = new Date();
StringBuffer now = new StringBuffer(d2.toString());
System. out .println(now);
return d2;
}
( 4 ) 隔離引用:這種情況中,被回收的對象仍具有引用,這種情況稱作隔離島。若存在這兩個實例,他們互相引用,并且這兩個對象的所有其他引用都刪除,其他任何線程無法訪問這兩個對象中的任意一個。也可以符合垃圾回收條件。
public class Island {
Island i ;
public static void main(String[] args) {
Island i2 = new Island();
Island i3 = new Island();
Island i4 = new Island();
i2. i =i3;
i3. i =i4;
i4. i =i2;
i2= null ;
i3= null ;
i4= null ;
}
}
(問題八:垃圾收集前進行清理 ------finalize() 方法) java 提供了一種機制,使你能夠在對象剛要被垃圾回收之前運行一些代碼。這段代碼位于名為 finalize() 的方法內,所有類從 Object 類繼承這個方法。由于不能保證垃圾回收器會刪除某個對象。因此放在 finalize() 中的代碼無法保證運行。因此建議不要重寫 finalize();
7.??? final 問題:
????? final 使得被修飾的變量 " 不變 " ,但是由于對象型變量的本質是 " 引用 " ,使得 " 不變 " 也有了兩種含義:引用本身的不變 ? ,和引用指向的對象不變。 ????????? 引用本身的不變:
final StringBuffer a= new StringBuffer( "immutable" );
final StringBuffer b= new StringBuffer( "not immutable" );
a=b; // 編譯期錯誤
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;// 編譯期錯誤
引用指向的對象不變:
final StringBuffer a= new StringBuffer( "immutable" );
a.append( " broken!" ); // 編譯通過
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!"); // 編譯通過
可見, final 只對引用的 " 值 "( 也即它所指向的那個對象的內存地址 ) 有效,它迫使引用只能指向初始指向的那個對象,改變它的指向會導致編譯期錯誤。至于它所指向的對象的變化, final 是不負責的。這很類似 == 操作符: == 操作符只負責引用的 " 值 " 相等,至于這個地址所指向的對象內容是否相等, == 操作符是不管的。在舉一個例子:
public class Name {
private String firstname ;
private String lastname ;
public String getFirstname() {
return firstname ;
}
public void setFirstname(String firstname) {
this . firstname = firstname;
}
public String getLastname() {
return lastname ;
}
public void setLastname(String lastname) {
this . lastname = lastname;
}
}
?
public class Name {
private String firstname;
private String lastname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
?
???????? 編寫測試方法:
public static void main(String[] args) {
final Name name = new Name();
name.setFirstname( "JIM" );
name.setLastname( "Green" );
System.out.println(name.getFirstname()+ " " +name.getLastname());
}
public static void main(String[] args) {
final Name name = new Name();
name.setFirstname("JIM");
name.setLastname("Green");
System.out.println(name.getFirstname()+" "+name.getLastname());
}
?
???????? 理解 final 問題有很重要的含義。許多程序漏洞都基于此 ----final 只能保證引用永遠指向固定對象,不能保證那個對象的狀態不變。在多線程的操作中 , 一個對象會被多個線程共享或修改,一個線程對對象無意識的修改可能會導致另一個使用此對象的線程崩潰。一個錯誤的解決方法就是在此對象新建的時候把它聲明為 final ,意圖使得它 " 永遠不變 " 。其實那是徒勞的。????????? Final 還有一個值得注意的地方:????????? 先看以下示例程序:
class Something {
final int i ;
public void doSomething() {
System. out .println( "i = " + i );
}
}
class Something {
final int i;
public void doSomething() {
System.out.println("i = " + i);
}
}
???????? 對于類變量, Java 虛擬機會自動進行初始化。如果給出了初始值,則初始化為該初始值。如果沒有給出,則把它初始化為該類型變量的默認初始值。但是對于用 final 修飾的類變量,虛擬機不會為其賦予初值,必須在 constructor ( 構造器 ) 結束之前被賦予一個明確的值。可以修改為 "final int i = 0;" 。
?
8.??? 如何把程序寫得更健壯:
???? 1 、 盡早釋放無用對象的引用。 好的辦法是使用臨時變量的時候,讓引用變量在退出活動域后,自動設置為 null ,暗示垃圾收集器來收集該對象,防止發生內存泄露。對于仍然有指針指向的實例, jvm 就不會回收該資源 , 因為垃圾回收會將值為 null 的對象作為垃圾,提高 GC 回收機制效率;
???? 2 、 定義字符串應該盡量使用 String str="hello"; 的形式 ,避免使用 String str = new String("hello"); 的形式。因為要使用內容相同的字符串,不必每次都 new 一個 String 。例如我們要在構造器中對一個名叫 s 的 String 引用變量進行初始化,把它設置為初始值,應當這樣做:
public class Demo {
private String s;
public Demo() {
s = "Initial Value" ;
}
}
?
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
? 而非
s =? new? String("Initial Value");?
s = new String("Initial Value");
????? 后者每次都會調用構造器,生成新對象,性能低下且內存開銷大,并且沒有意義,因為 String 對象不可改變,所以對于內容相同的字符串,只要一個 String 對象來表示就可以了。也就說,多次調用上面的構造器創建多個對象,他們的 String 類型屬性 s 都指向同一個對象。?????

3 、我們的程序里不可避免大量使用字符串處理,避免使用 String ,應 大量使用 StringBuffer ,因為 String 被設計成不可變 (immutable) 類,所以它的所有對象都是不可變對象,請看下列代碼;
String s = "Hello";??
s = s + " world!";?
String s = "Hello";
s = s + " world!";
??????? 在這段代碼中, s 原先指向一個 String 對象,內容是 "Hello" ,然后我們對 s 進行了 + 操作,那么 s 所指向的那個對象是否發生了改變呢?答案是沒有。這時, s 不指向原來那個對象了,而指向了另一個 String 對象,內容為 "Hello world!" ,原來那個對象還存在于內存之中,只是 s 這個引用變量不再指向它了。????????? 通過上面的說明,我們很容易導出另一個結論,如果經常對字符串進行各種各樣的修改,或者說,不可預見的修改,那么使用 String 來代表字符串的話會引起很大的內存開銷。因為 String 對象建立之后不能再改變,所以對于每一個不同的字符串,都需要一個 String 對象來表示。這時,應該考慮使用 StringBuffer 類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。并且,這兩種類的對象轉換十分容易。
???? 4 、 盡量少用靜態變量 ,因為靜態變量是全局的, GC 不會回收的;
???? 5 、 盡量避免在類的構造函數里創建、初始化大量的對象 ,防止在調用其自身類的構造器時造成不必要的內存資源浪費,尤其是大對象, JVM 會突然需要大量內存,這時必然會觸發 GC 優化系統內存環境;顯示的聲明數組空間,而且申請數量還極大。????????? 以下是初始化不同類型的對象需要消耗的時間:

運算操作???
?示例????
?標準化時間
?
本地賦值????
?i = n
?1.0
?
實例賦值????
?this.i = n
?1.2
?
方法調用????
?Funct()
?5.9
?
新建對象????
?New Object()
?980
?
新建數組????
?New int[10]
?3100
?

???????
從表 1 可以看出,新建一個對象需要 980 個單位的時間,是本地賦值時間的 980 倍,是方法調用時間的 166 倍,而新建一個數組所花費的時間就更多了。
???? 6 、盡量在合適的場景下使用 對象池技術 以提高系統性能,縮減縮減開銷,但是要注意對象池的尺寸不宜過大,及時清除無效對象釋放內存資源,綜合考慮應用運行環境的內存資源限制,避免過高估計運行環境所提供內存資源的數量。
???? 7 、大集合對象擁有大數據量的業務對象的時候,可以考慮 分塊進行處理 ,然后解決一塊釋放一塊的策略。
???? 8 、 不要在經常調用的方法中創建對象 ,尤其是忌諱在循環中創建對象。可以適當的使用 hashtable , vector 創建一組對象容器,然后從容器中去取那些對象,而不用每次 new 之后又丟棄。
???? 9 、一般都是發生在開啟大型文件或跟數據庫一次拿了太多的數據,造成 Out Of Memory Error 的狀況,這時就大概要計算一下數據量的最大值是多少,并且設定所需最小及最大的內存空間值。
???? 10 、盡量少用 finalize 函數 ,因為 finalize() 會加大 GC 的工作量,而 GC 相當于耗費系統的計算能力。
??? 11 、 不要過濫使用哈希表 ,有一定開發經驗的開發人員經常會使用 hash 表( hash 表在 JDK 中的一個實現就是 HashMap )來緩存一些數據,從而提高系統的運行速度。比如使用 HashMap 緩存一些物料信息、人員信息等基礎資料,這在提高系統速度的同時也加大了系統的內存占用,特別是當緩存的資料比較多的時候。其實我們可以使用操作系統中的緩存的概念來解決這個問題,也就是給被緩存的分配一個一定大小的緩存容器,按照一定的算法淘汰不需要繼續緩存的對象,這樣一方面會因為進行了對象緩存而提高了系統的運行效率,同時由于緩存容器不是無限制擴大,從而也減少了系統的內存占用。現在有很多開源的緩存實現項目,比如 ehcache 、 oscache 等,這些項目都實現了 FIFO 、 MRU 等常見的緩存算法

?

本文來自CSDN博客,轉載請標明出處: http://blog.csdn.net/forlong401/archive/2011/03/10/6237113.aspx

JAVA 內存管理總結


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品视频网站 | 一区二区中文 | 欧美日一区二区 | 欧美激情综合网 | 天天插天天舔 | 亚洲午夜精品一区二区三区他趣 | 色视频一区| 首页亚洲国产丝袜长腿综合 | 国产精彩视频 | 亚洲精品中文字幕乱码一区二区 | 久久精品一区二区三区四区 | 自拍偷拍中文字幕 | 真实做爰对白录音 | 日本精品久久久久中文字幕2 | 日韩欧美一区二区在线观看 | 看毛片网站 | 国产美女在线免费观看 | 免费午夜不卡毛片 | 久久婷婷在线 | 亚洲高清一区二区三区 | 亚洲三级在线 | 丁香六月综合 | 欧美日韩中文字幕 | 亚洲性人人天天夜夜摸 | 日韩国产成人资源精品视频 | 欧美日韩亚洲视频 | 色婷婷五| 国产网站在线播放 | 欧日韩不卡在线视频 | 婷婷97狠狠的狠狠的爱 | 色免费看 | 性欧美高清极品猛交 | 日韩欧美一区二区三区四区 | 美女伊人| 99re国产 | 国产免费av在线 | vidz 98hd| 色播在线永久免费视频网站 | 天天干夜夜操 | 国产人妻人伦精品潘金莲 | 日韩午夜伦y4480私人影院 |