日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

ie传递给系统调用的数据区域太小_内存区域与内存溢出异常

發布時間:2023/12/10 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ie传递给系统调用的数据区域太小_内存区域与内存溢出异常 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自動內存管理機制

運行時數據區:Java虛擬機定義了在程序執行期間使用的各種運行時數據區域。其中一些數據區域是在Java虛擬機啟動時創建的,僅在Java虛擬機退出時銷毀。其他數據區域是每個線程所占的空間。線程數據區域是隨著線程銷毀和創建的。

PC 寄存器(程序計數器)線程私有:Java虛擬機可以同時支持許多執行線程。每個Java虛擬機線程都有自己的pc(程序計數器)寄存器。在任何時候,每個Java虛擬機線程都在執行單個方法的代碼,即該線程的當前方法。如果該方法不是native方法,則pc寄存器包含當前正在執行的Java虛擬機指令的地址。如果線程當前正在執行的方法是native的,則Java虛擬機的pc寄存器的值是未定義的。Java虛擬機的pc寄存器足夠寬,可以在特定平臺上保存returnAddress或native 指針。

java虛擬機棧(線程私有):每個Java虛擬機線程都有一個私有Java虛擬機棧,與線程同時創建。Java虛擬機棧存儲。Java虛擬機棧類似于傳統語言的棧,例如C:它保存局部變量和部分結果,并在方法調用和返回中起作用。由于除了壓入和彈出幀之外,永遠不會直接操作Java虛擬機棧,而幀可以是堆分配的。所以 Java虛擬機棧的內存不需要是連續的。

在Java?虛擬機規范的第一版中,Java虛擬機棧和Java棧是一個意思。

此規范允許Java虛擬機棧具有固定大小或根據計算的需要動態擴展和收縮。如果Java虛擬機堆棧具有固定大小,則可以在創建該棧時獨立選擇每個Java虛擬機堆棧的大小。

Java虛擬機實現可以為程序員或用戶提供對Java虛擬機棧的初始大小的控制,以及在動態擴展或收縮Java虛擬機堆棧的情況下,控制最大和最小大小。

以下異常條件與Java虛擬機堆棧相關聯:

  • 如果線程中的計算需要比允許的更大的Java虛擬機堆棧,則Java虛擬機會拋出StackOverflowError.

  • 如果可以動態擴展Java虛擬機堆棧,并且嘗試進行擴展但可以使用的內存不足以實現擴展,或者可以使用的內存不足以為新線程創建初始Java虛擬機堆棧,則可以使用Java虛擬機拋出OutOfMemoryError.

堆(線程共有):Java虛擬機有一個在所有Java虛擬機線程之間共享的堆。堆是運行時數據區,從中分配所有類實例和數組的內存

堆是在虛擬機啟動時創建的。存儲在堆上的對象由自動存儲管理系統(稱為垃圾收集器)回收 ; 對象永遠不會被用戶顯式釋放。Java虛擬機假設沒有特定類型的自動存儲管理系統,可以根據實現者的系統要求選擇存儲管理技術。堆可以是固定大小的,或者可以根據計算的需要進行擴展,如果不需要更大的堆,則可以收縮。堆的內存不需要是連續的。

Java虛擬機實現可以為程序員或用戶提供對堆的初始大小的控制,以及如果可以動態擴展或收縮堆,則控制最大和最小堆大小。

以下異常情況與堆相關聯:

  • 如果計算需要的堆的大小超過自動存儲管理系統可用的堆,則Java虛擬機會拋出OutOfMemoryError。

方法區(線程共有):Java虛擬機具有在所有Java虛擬機線程之間共享的方法區域。方法區域類似于傳統語言的編譯代碼的存儲區域或類似于操作系統進程中的“文本”段。它存儲每個類的結構,例如運行時常量池,字段和方法數據,以及方法和構造函數的代碼,包括類和接口初始化以及實例初始化中使用的特殊方法

方法區域是在虛擬機啟動時創建的。雖然方法區域在邏輯上是堆的一部分,但是簡單的虛擬機實現可能選擇不進行垃圾收集或壓縮它。此規范不強制方法區域的位置或用于管理編譯代碼的策略。方法區域可以是固定大小的,或者可以根據計算的需要進行擴展,并且如果不需要更大的方法區域,則可以縮小方法區域。方法區域的內存不需要是連續的。

Java虛擬機實現可以為程序員或用戶提供對方法區域的初始大小的控制,以及在變大小方法區域的情況下,控制最大和最小方法區域大小。

以下異常條件與方法區域相關聯:

  • 如果方法區域中的內存不能滿足分配請求,則Java虛擬機會拋出OutOfMemoryError。

運行時常量池(在棧中線程共有,在方法區中):運行時常量池在每個類或者接口的class文件中代表?constant_pool表。?它包含幾種常量,從編譯時已知的字面量到必須在運行時解析的方法和字段引用。運行時常量池提供類似于傳統編程語言的符號表的功能,盡管它包含比典型符號表更寬范圍的數據。

每個運行時常量池都是從Java虛擬機的方法區域分配的。當Java虛擬機創建類或接口時,將構造類或接口的運行時常量池。

以下異常條件與類或接口的運行時常量池的構造相關聯:

  • 創建類或接口時,如果運行時常量池的構造需要的內存比Java虛擬機的方法區域中可用的內存多,則Java虛擬機會拋出OutOfMemoryError。

本地方法棧(線程私有):Java虛擬機的實現可以使用傳統的堆棧,俗稱“C堆棧”,以支持native方法(用Java編程語言以外的語言編寫的方法)。native方法堆棧也可以通過以諸如C語言的語言為Java虛擬機的指令集實現解釋器來使用。無法加載native方法并且本身不依賴于傳統堆棧的Java虛擬機實現不需要提供本機方法棧。如果提供,則通常在創建每個線程時為每個線程分配native方法堆棧。

此規范允許本機方法堆棧具有固定大小或根據計算的需要動態擴展和收縮。如果本機方法堆棧具有固定大小,則可以在創建該堆棧時獨立地選擇每個本機方法堆棧的大小。

Java虛擬機實現可以為程序員或用戶提供對本機方法堆棧的初始大小的控制,以及在不同大小的本機方法堆棧的情況下,控制最大和最小方法堆棧大小。

以下異常條件與本機方法堆棧相關聯:

  • 以下異常條件相關聯如果線程中的計算需要比允許的更大的本機方法堆棧,則Java虛擬機會拋出StackOverflowError。

  • 如果可以動態擴展native方法堆棧并嘗試native方法棧擴展但可用內存不足,或者如果可用內存不足以為新線程創建初始本機方法堆棧,則Java虛擬機會拋出OutOfMemoryError?。

分段代碼緩存(HotSpot)

代碼緩存是Java虛擬機存儲生成的本機代碼的內存區域。它被組織為一個連續的內存塊上的單個堆數據結構。

代碼緩存不是只有一個代碼堆,而是分成多個段,每個段包含特定類型的編譯代碼。此分段可以更好地控制JVM內存占用,縮短編譯方法的掃描時間,顯著減少代碼緩存的碎片,并提高性能。

代碼緩存分為以下三個部分:

代碼緩存段描述JVM命令行參數
Non-method此代碼堆包含非方法代碼,例如編譯器緩沖區和字節碼解釋器。此代碼類型永遠保留在代碼緩存中。代碼堆具有3 MB的固定大小,并且剩余的代碼緩存在分析的和非分析的代碼堆之間均勻分布。-XX:NonMethodCodeHeapSize
Profiled此代碼堆包含使用壽命較短的輕微優化的配置文件方法。–XX:ProfiledCodeHeapSize
Non-profiled此代碼堆包含完全優化的非分析方法,可能具有較長的生命周期。-XX:NonProfiledCodeHeapSize

棧幀

棧幀用于存儲數據和部分結果,以及執行動態鏈接,返回方法的值以及調度異常。

每次調用方法時都會創建一個新幀。當方法調用完成時,無論是正常完成或者拋出異常(它會拋出未捕獲的異常),棧幀都將被銷毀。幀是從創建幀的線程的Java虛擬機棧分配的。?每個幀都有自己的局部變量數組,自己的操作數棧,以及對當前方法所在類的運行時常量池的引用

可以使用附加的特定于實現的信息來擴展幀,例如調試信息。

局部變量數組和操作數堆棧的大小在編譯時確定,并與用于與棧幀相關聯的方法的代碼一起提供。因此,幀數據結構的大小僅取決于Java虛擬機的實現,并且可以在方法調用上同時分配這些結構的存儲器。

只有一個幀(執行方法的幀)在給定控制線程中的任何點處都是活動的。該幀被稱為當前幀,并且其方法被稱為當前方法。定義當前方法的類是當前類。局部變量和操作數堆棧的操作通常參考當前幀。

如果棧幀的方法調用另一個方法或其方法完成,則此棧幀將不再是當前棧幀。調用方法時,會創建一個新幀,并在控制轉移到新方法時成為當前幀。在方法返回時,當前幀將其方法調用的結果(如果有)傳遞回前一幀。然后當前一幀變為當前幀時丟棄當前幀。

請注意,由線程創建的幀是線程私有的,并且不能被任何其他線程引用。

本地變量表:每個幀包含一個稱為局部變量的變量數組。幀的局部變量數組的長度在編譯時確定,并以類或接口的二進制表示形式提供,同時提供與幀相關的方法的代碼。

單個局部變量可以包含boolean,byte,char,short,int,float,reference或returnAddress類型的值。一對局部變量可以包含long或double類型的值。

通過索引來確定局部變量的位置。第一個局部變量的索引為零。索引的大小介于0和局部變量數組長度 - 1之間。

long類型或double類型的值占用兩個連續的局部變量。只能使用較小的索引來處理這樣的值。例如,存儲在索引 n 的局部變量數組中的double類型實際上占用索引為n和n + 1的局部變量; 但是,索引n + 1的局部變量無法加載,它可以存儲到。只能通過索引 n 獲取。

Java虛擬機不要求n是偶數。直觀地說,long和double類型的值不需要在局部變量數組中進行64位對齊。實現者可以使用為該值保留的兩個局部變量自由決定表示此類值的適當方式。

Java虛擬機使用局部變量在方法調用上傳遞參數。在類方法(static方法)調用中,任何參數都是從局部變量0開始的連續局部變量中傳遞的。在實例方法調用中,局部變量0總是用于傳遞對調用實例方法的對象的引用(在Java)。隨后,任何參數都在從局部變量1開始的連續局部變量中傳遞。

操作數棧:每個棧幀里包含一個后進先出(LIFO)堆棧,稱為其操作數堆棧。棧幀的操作數棧的最大深度在編譯時確定,并與用于與棧幀相關聯的方法的代碼一起提供。

在上下文清晰的地方,我們有時會將當前幀的操作數棧稱為操作數棧。

當創建包含操作數棧的幀時,操作數堆棧為空。Java虛擬機提供指令以將局部變量或字段中的常量或值加載到操作數堆棧上。其他Java虛擬機指令從操作數堆棧獲取操作數,對它們進行操作,并將結果推回操作數堆棧。操作數堆棧還用于準備要傳遞給方法和接收方法結果的參數。

例如,iadd指令將兩個int值一起添加。它要求要添加的int值是操作數堆棧的前兩個值,由前面的指令推送到那里。兩個int值都從操作數堆棧中彈出。它們相加后的總和被推回到操作數堆棧上。子計算可以嵌套在操作數堆棧上,從而產生可以由包含計算使用的值。

操作數堆棧上的每個條目都可以包含任何Java虛擬機類型的值,包括long類型或double類型的值。

必須以適合其類型的方式操作操作數堆棧中的值。例如,不可能推送兩個int值,然后將它們視為long或推送兩個float值,然后使用iadd指令添加它們。少量Java虛擬機指令(dup指令和交換)作為原始值在運行時數據區域上運行,而不考慮它們的特定類型; 這些指令的定義方式使它們不能用于修改或分解單個值。操作數堆棧操作的這些限制是通過類文件驗證強制執行的。

在任何時間點,操作數堆棧都具有相關聯的深度,其中long或double類型的值對深度貢獻兩個單位,而任何其他類型的值貢獻一個單位。

動態鏈接:每個棧幀都包含一個指向運行時常量池的引用,持有這個引用是為了支持方法調用過程中的動態鏈接。Class 文件的常量池中存有大量的符號引用,字節碼中的方法調用指令就以常量池中指向方法的符號引用作為參數。這些符號引用一部分會在類加載階段或者第一次使用的時候就轉換為直接引用,這種轉化成為靜態解析。另外一部分將在每一次運行期間轉化為直接引用,這部分成為動態鏈接。

(jvm 規范)方法的 class 文件代碼是指要調用的方法和要通過符號引用訪問的變量。動態鏈接將這些符號方法引用轉換為具體的方法引用,根據需要加載類以解析尚未定義的符號,并將變量訪問轉換為與這些變量的運行時位置相關聯的存儲結構中的適當偏移。

方法和變量的這種后期綁定使得方法使用的其他類中的更改不太可能破壞此代碼。

正常情況下完成方法調用:如果調用不會直接從Java虛擬機或執行顯式throw語句引發異常,則方法調用會正常完成。如果當前方法的調用正常完成,則可以將值返回給調用方法。當被調用的方法執行其中一個返回指令時,就會發生這種情況,返回指令的選擇必須適合于返回值的類型(如果有的話)。

在這種情況下,當前幀用于恢復調用者的狀態,包括其局部變量和操作數堆棧,調用者的程序計數器適當地遞增以跳過方法調用指令。然后執行在調用方法的幀中正常繼續,返回值(如果有)被推送到該幀的操作數堆棧。

發生異常的方法調用:如果在方法中執行Java虛擬機指令導致Java虛擬機拋出異常,并且該異常未在該方法中處理,則方法調用突然完成。執行athrow指令還會導致顯式拋出異常,如果當前方法未捕獲異常,則會導致突然的方法調用完成。突然完成的方法調用永遠不會向其調用者返回值。

對象的表示:Java虛擬機不要求對象的任何特定內部結構。

在Oracle的一些Java虛擬機實現中,對類實例的引用是指向句柄的指針,該句柄本身是一對指針:一個指向包含對象方法的表和一個指向表示Class對象的指針 對象的類型,另一個是從堆中為對象數據分配的內存。

特殊方法


實例初始化方法

類具有零個或多個實例初始化方法,每個方法通常對應于用Java編程語言編寫的構造函數。

  • 如果滿足以下所有條件,則方法是實例初始化方法:

  • 它在類(不是接口)中定義。

  • 它具有特殊名稱

  • 它是void?返回類型

在類中,任何名為的非void方法都不是實例初始化方法。在接口中,任何名為的方法都不是實例初始化方法。任何Java虛擬機指令都不能調用此類方法,并且格式檢查會拒絕這些方法。

實例初始化方法的聲明和使用受Java虛擬機的約束。對于聲明,方法的 access_flags 項和代碼數組受到約束。對于使用,實例初始化方法可以僅由未初始化的類實例上的invokespecial指令調用。

因為名稱不是Java編程語言中的有效標識符,所以它不能直接用在用Java編程語言編寫的程序中。

類初始化方法:類或接口最多只有一個類或接口初始化方法,并由調用該方法的Java虛擬機初始化。

如果滿足以下所有條件,則方法是類或接口初始化方法:

  • 它的特殊名稱是

  • 它是void?返回類型

  • 在版本號為51.0或更高的類文件中,該方法設置了ACC_STATIC標志并且不帶參數

在Java SE 7中引入了對 ACC_STATIC 的要求,并且在Java SE 9中沒有引用參數。在版本號為50.0或更低的類文件中,名為的void 方法被認為是類或接口初始化方法 無論其ACC_STATIC標志的設置或是否需要參數。

類文件中名為的其他方法不是類或接口初始化方法。它們永遠不會被Java虛擬機本身調用,不能被任何Java虛擬機指令調用,并且會被格式檢查拒絕。

因為名稱不是Java編程語言中的有效標識符,所以它不能直接用在用Java編程語言編寫的程序中。

簽名多態方法:如果滿足以下所有條件,則方法是簽名多態的:

  • 它在java.lang.invoke.MethodHandle類或java.lang.invoke.VarHandle類中聲明。

  • 它有一個Object []?類型的形式參數。

  • 它設置了ACC_VARARGS和ACC_NATIVE標志。

對象的創建

虛擬機遇到一條new命令時,首先將去檢查這個指令的參數是否能在常量池中定位到一個符號引用,并且檢查這個符號的引用代表的類是否已被加載、解析和初始化過。如果沒有則必須執行相應的加載過程。

在類加載檢查通過后,接下來虛擬機將為新生對象分配內存。對象所需要的內存大小在類加載完成后便可以完全確定,為對象分配空間的任務等同于把一塊大小確定的內存從java堆中劃分出來。在使用Serial、ParNew等需要壓縮的收集器時,使用“指針碰撞”方式壓縮內存:假設java堆中內存是絕對規整的,所有用過的內存都放在一遍,空閑的放在另一邊。中間放著指針作為分界點的指示器,當需要為對象分配內存的時候需要做的就是將指針向空閑一側分配與對象大小相等的距離。而使用CMS 這種就Mark-Swap 算法的收集器時,通常采用空閑列表:如果java堆的內存分配并不是規整的,已使用的和未使用的內存相互交錯,虛擬機就必須維護一個列表,記錄那些內存塊是可用的,在分配的時候從內存列表中找出一塊足夠大的空間劃分給對象實例,并更新在表上的記錄。這種方式成為空閑列表。

除如何劃分可用空間外,還有另外一個需要考慮的問題是對象創建在虛擬機中是非常頻繁的行為,即使是僅僅修改一個指針所指向的位置,在并發情況下并不是線程安全的,可能出現正在給A分配內存,指針還沒來得及修改,對象B又同時使用了原來的指針分配內存的情況。解決這種問題有兩個方案,一種是對分配內存空間的動作進行同步處理——實際上虛擬機采用CAS 配上失敗重試的方式保證更新操作的原子性;另一種是把內存分配的動作按照線程劃分在不同的空間中進行,即每一個線程在java堆中預先分配一小塊內存,成為本地線程分配緩沖(Thread Local Allocation Buffer , TLAB) 。那個線程要分配內存就在那個線程的TLAB上分配,只有TLAB用完并更新分配時,才需要同步鎖定。虛擬機是否使用TLAB,可以通過 -XX:+/- UseTLAB 參數設定。

內存分配后,虛擬機需要將分配到的內存空間都初始化零值(不包括對象頭),如果使用TLAB ,這一工作過程也可以提前至TLAB分配時進行。這一步操作保證了對象的實例字段在java代碼中可以不賦初始值就直接使用,程序能訪問到這些字段的數據類型所對應的零值。

接下來,虛擬機要對對象進行必要的設置,例如這個對象是那個類的實例、如何才能找到類的元數據信息,對象的哈希碼、對象的GC分帶年齡信息。這些信息存放在對象的對象頭中(Object Header)之中。根據虛擬機當前的運行狀態的不同,是否啟用鎖偏向等,對象頭還會有不同的設置方式。

在上面的工作都完成之后,從虛擬機的角度來看,一個新的對象已經產生了。但從java程序的角度來看,對象的創建才剛剛開始——方法還沒有執行,所有的字段都還為零值。所以,一般來說(由字節碼中是否跟隨 invokespecial 指令所決定),執行new指令之后會接著執行方法,把對象按照程序員的意愿進行初始化,這樣一個真正可用的對象才算完全產生出來。

對象的內存布局

在HotSpot虛擬機中,對象在內存中存儲的布局可以分為3塊區域:對象頭(Header)、實例數據(Instance Data)、和對齊填充(Padding)。

HotSpot 虛擬機的對象頭包括兩部分信息,第一部分用于存儲對象自身的運行時數據,如哈希嗎,GC分代年齡標志、鎖狀態年齡標志、線程持有的鎖、偏向線程ID、偏向時間戳等,這部分數據的長度在32位和64位的虛擬機(未開啟壓縮指針)中分別為32bit和64bit,官方稱它為“Mark Word”。對象需要存儲的運行時數據很多,其實已經超出了32位、64位 BitMap結構所能記錄的限度,但是對象頭信息時與對象自身定義無關的額外存儲成本,考慮到虛擬機的空間效率,Mark Work被設計成一個非固定的數據結構以便在極小的空間內存儲更多的信息。它會根據對象的狀態復用自己的空間。例如,在32位的HotSpot虛擬機中,如果對象處于未被鎖定的狀態下,那么 Mark Word 的32bit 空間中的25bit用于存儲對象Hash碼,4比特用于存儲對象分代年齡,2bit用于存儲鎖標志位,1bit固定為0,而在其他狀態(輕量級鎖定,重量級鎖定,GC標記,可偏向)見下表:

存儲內容標志位狀態
對象哈希碼、對象分代年齡01未鎖定
指向鎖記錄的指針00輕量級鎖定
指向重量級記錄的指針10膨脹(重量級鎖定)
空,不需要記錄信息11GC標記
偏向線程ID、偏向時間戳、對象分代年齡01可偏向

對象頭的另外一部分是類型指針,即對象指向他的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪一個類的實例。并不是所有的虛擬機實現都必須在對象數據上保留類型指針,換句話說,查找對象的元數據信息不一定要經過對象本身。另外如果對象是一個java數組,那在對象頭中還必須有一塊用于記錄數組長度的數據,因為虛擬機可以通過普通java 對象的元數據信息確定java 對象的大小,但是從java 數組中的元數據中確無法確定數組的大小。

接下來的實例數據部分是對象真正存儲的有效信息,也是是在程序代碼中所定義的各種字段內容。無論是從父類繼承下來的還是從子類定義的,都需要記錄下來。這部分的存儲順序會受到虛擬機分配參數策略(FieldAllocationStyle)和字段在java源碼中定義順序的影響。HotSpot虛擬機默認的分配策略為 longs/doubles 、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers),從分配策略中可以看出,相同寬度的字段總是被分配到一起。在滿足這個前提條件的情況下,父類中定義的變量會出現在子類之前。如果CompactFields參數值為true,那么子類中較窄的變量也可能會插入到父類變量的空隙只中。

第三部分對齊填充不是必然存在的,也沒有特別的含義,它僅僅起著占位符的作用。由于HotSpot VM的自動內存管理系統要求起始對象的起始地址必須是8字節的整數倍,換句話說,就是對象的大小必須是8字節的整數倍。而對象頭部分正好是8字節的倍數,因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。

對象的訪問定位

java程序需要通過棧上的reference 數據來操作堆上的具體對象。目前主流方式有句柄和直接使用指針兩種。

如果使用句柄訪問的話,那么java堆中將會劃分出一塊內存來作為句柄池,reference中存儲的對象就是對象的句柄地址,而句柄中包含了對象實例數據與類型數據各自的地址信息。

如果使用直接指針訪問,那么java堆對象的布局中就必須考慮如何放置訪問類型數據的相關信息,而reference 中存儲的直接就是對象地址。

內存溢出

內存溢出原因:

對于java運行時數據區來說,都會因為申請內存失敗而拋出OutOfMemoryError

java堆溢出:只要不斷的創建對象,并保證GC Roots到對象之間有可達路徑來避免垃圾收集器回收這些對象,那么在對象數量達到最大堆的容量限制之后就會拋出OutOfMemoryError。

虛擬機棧和本地方法棧溢出:一般情況下在線程過多的時候,每個線程分配的棧深度不夠的時候有可能拋出OutOfMemoryError。

方法區和運行時常量池溢出:運行時生成大量類。

本機直接內存溢出:java 1.8 用Unsafe 手動分配內存,直接操作DirectByteBuffer是通過計算得知,手動拋出的。

對于CMS收集器來說:如果在垃圾收集中花費了太多時間,CMS收集器會拋出OutOfMemoryError:如果超過98%的總時間花在垃圾收集上,并且回收的堆少于2%,那么拋出OutOfMemoryError?。

總結

以上是生活随笔為你收集整理的ie传递给系统调用的数据区域太小_内存区域与内存溢出异常的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。