導航:首頁 > 編程語言 > 垃圾收集java

垃圾收集java

發布時間:2023-02-05 06:50:59

『壹』 java垃圾收集如何工作

ava垃圾收集是管理程序使用的運行時內存的自動過程。通過這樣做,自動JVM可以減輕程序員在程序中分配和釋放內存資源的開銷。
Java垃圾收集GC啟動
程序員不必在代碼中明確地啟動垃圾收集過程。System.gc() 和 Runtime.gc() 是用於請求JVM啟動垃圾收集過程的鉤子。
盡管該請求機制為程序員提供了啟動該過程的機會,但是該ONU在JVM上。它可以選擇拒絕該請求,因此不能保證這些調用將執行垃圾收集。該決定是由JVM基於堆內存中的Eden空間可用性決定的。JVM規范將此選項保留在實現中,因此這些詳細信息是特定實現的。

『貳』 java有哪些垃圾回收演算法

常用的垃圾回收演算法有:
(1).引用計數演算法:
給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器都為0的對象就是不再被使用的,垃圾收集器將回收該對象使用的內存。
引用計數演算法實現簡單,效率很高,微軟的COM技術、ActionScript、Python等都使用了引用計數演算法進行內存管理,但是引用計數演算法對於對象之間相互循環引用問題難以解決,因此java並沒有使用引用計數演算法。
(2).根搜索演算法:
通過一系列的名為「GC Root」的對象作為起點,從這些節點向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Root沒有任何引用鏈相連時,則該對象不可達,該對象是不可使用的,垃圾收集器將回收其所佔的內存。
主流的商用程序語言C#、java和Lisp都使用根搜素演算法進行內存管理。
在java語言中,可作為GC Root的對象包括以下幾種對象:
a. java虛擬機棧(棧幀中的本地變數表)中的引用的對象。
b.方法區中的類靜態屬性引用的對象。
c.方法區中的常量引用的對象。
d.本地方法棧中JNI本地方法的引用對象。
java方法區在Sun HotSpot虛擬機中被稱為永久代,很多人認為該部分的內存是不用回收的,java虛擬機規范也沒有對該部分內存的垃圾收集做規定,但是方法區中的廢棄常量和無用的類還是需要回收以保證永久代不會發生內存溢出。
判斷廢棄常量的方法:如果常量池中的某個常量沒有被任何引用所引用,則該常量是廢棄常量。
判斷無用的類:
(1).該類的所有實例都已經被回收,即java堆中不存在該類的實例對象。
(2).載入該類的類載入器已經被回收。
(3).該類所對應的java.lang.Class對象沒有任何地方被引用,無法在任何地方通過反射機制訪問該類的方法。
Java中常用的垃圾收集演算法:
(1).標記-清除演算法:
最基礎的垃圾收集演算法,演算法分為「標記」和「清除」兩個階段:首先標記出所有需要回收的對象,在標記完成之後統一回收掉所有被標記的對象。
標記-清除演算法的缺點有兩個:首先,效率問題,標記和清除效率都不高。其次,標記清除之後會產生大量的不連續的內存碎片,空間碎片太多會導致當程序需要為較大對象分配內存時無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集動作。
(2).復制演算法:
將可用內存按容量分成大小相等的兩塊,每次只使用其中一塊,當這塊內存使用完了,就將還存活的對象復制到另一塊內存上去,然後把使用過的內存空間一次清理掉。這樣使得每次都是對其中一塊內存進行回收,內存分配時不用考慮內存碎片等復雜情況,只需要移動堆頂指針,按順序分配內存即可,實現簡單,運行高效。
復制演算法的缺點顯而易見,可使用的內存降為原來一半。
(3).標記-整理演算法:
標記-整理演算法在標記-清除演算法基礎上做了改進,標記階段是相同的標記出所有需要回收的對象,在標記完成之後不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,在移動過程中清理掉可回收的對象,這個過程叫做整理。
標記-整理演算法相比標記-清除演算法的優點是內存被整理以後不會產生大量不連續內存碎片問題。
復制演算法在對象存活率高的情況下就要執行較多的復制操作,效率將會變低,而在對象存活率高的情況下使用標記-整理演算法效率會大大提高。
(4).分代收集演算法:
根據內存中對象的存活周期不同,將內存劃分為幾塊,java的虛擬機中一般把內存劃分為新生代和年老代,當新創建對象時一般在新生代中分配內存空間,當新生代垃圾收集器回收幾次之後仍然存活的對象會被移動到年老代內存中,當大對象在新生代中無法找到足夠的連續內存時也直接在年老代中創建。

『叄』 說說JVM常用垃圾回收器的特點、優劣勢、使用場景和參數設置

Java中的垃圾回收器幾乎是面試中的必考點,無論是面試初級,中級還是高級,總免不了要問一問垃圾回收器的一些知識點。不管在實際開發中你使用程度怎麼樣,為了面試不被壓價,還是非常有必要對它做一個較深入的理解。

本篇對JVM中常用的幾種垃圾回收器的主要特點,使用場景及優化建議做一個簡單介紹,希望起到拋磚引玉的效果,對你入門有所幫助。

新生代回收器

老年代回收器

新生代和老年代回收器

Serial收集器是最基本、發展 歷史 最悠久的收集器。JDK1.3.1前是HotSpot新生代收集的唯一選擇。

運行示意圖

有如下特點:

簡單高效,由於採用的是單線程的方法,因此與其他類型的收集器相比,對單個cpu來說沒有了上下文之間的的切換,效率比較高。

會在用戶不知道的情況下停止所有工作線程。

在用戶的桌面應用場景中,可用內存一般不大,可以在較短時間內完成垃圾收集,只要不頻繁發生,這是可以接受的

對於限定單個CPU的環境來說,Serial收集器沒有線程切換開銷,可以獲得最高的單線程收集效率

ParNew收集器其實就是Serial收集器的多線程版本,除了使用多線程進行垃圾收集之外,其餘均和Serial 收集器一致。

運行示意圖

多線程版本的Serial,可以更加有效地利用系統資源

同Serial,會在用戶不知道的情況下停止所有工作線程

Server模式下使用,亮點是除Serial外,目前只有它能與CMS收集器配合工作,是一個非常重要的垃圾回收器。

運行示意圖

有如下特點:

追求高吞吐量,高效利用CPU,使吞吐量優先,且能進行精確控制。

根據相關特性,我們很容易想到它的使用場景,即:當應用程序運行在具有多個CPU上,對暫停時間沒有特別高的要求時,程序主要在後台進行計算,而不需要與用戶進行太多交互等就特別適合ParNew收集器。

Serial Old是Serial收集器的老年代版本,同樣是一個單線程收集器,使用標記-整理演算法。

有如下特點:

優劣勢基本和Serial無異,它是和Serial收集器配合使用的老年代收集器。

CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。採用的演算法是「標記-清除」,運作過程分為四個步驟:

運行示意圖

有如下特點:

如常見WEB、B/S系統的伺服器上的應用。

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」演算法,可以充分利用多核CPU的計算能力。

有如下特點:

優劣勢參考Parallel Scavenge收集器。

這樣在注重吞吐量以及CPU資源敏感的場景,就有了Parallel Scavenge(新生代)加Parallel Old(老年代)收集器的"給力"應用組合;

G1(Garbage-First)是JDK7-u4才推出商用的收集器

有如下特點:

G1收集器是當今收集器技術發展的最前沿成果。

G1 需要記憶集 (具體來說是卡表)來記錄新生代和老年代之間的引用關系,這種數據結構在 G1 中需要佔用大量的內存,可能達到整個堆內存容量的 20% 甚至更多。而且 G1 中維護記憶集的成本較高,帶來了更高的執行負載,影響效率。

按照《深入理解Java虛擬機》作者的說法,CMS 在小內存應用上的表現要優於 G1,而大內存應用上 G1 更有優勢,大小內存的界限是6GB到8GB。

個人以為G1已經基本全面壓制cms、parallel等回收器,缺點見上面的劣勢。但如果不是追求極致的性能,基本可以無腦G1

基本就介紹這些了,垃圾回收器基本不變的知識點多,學會(理解)可以應付N年的相關知識的面試,又是高頻面試考點,各位同學還是值得在這塊下點功夫的。文中有任何不足,錯誤歡迎指出,共同進步!

『肆』 java中垃圾回收機制的原理是什麼

回收機制就是 當一些資源被創建使用之後或不在調用的話 就會變成垃圾,垃圾的話會佔用空間,這時候就需要釋放空間給其他程序使用,所以JAVA擁有自動垃圾回收機制。

  1. GC的工作原理: 引用計數,標記復制"引用計數"是一種簡單但速度很慢的垃圾回收技術.

  2. "標記復制"的運行機制,垃圾回收器遍歷包含所有引用的列表,當發現存活的對象引用時做上標記,這樣當遍歷完所有對象引用並做上標記的時候,執行垃圾回收,將沒有標記的對象堆空間釋放.

  3. 垃圾回收機制的優點:Java的垃圾回收機制使得java程序員不用擔心內存空間的分配,減少了內存溢出.但同時也犧牲了一定的性能.

『伍』 JVM垃圾收集機制

JVM垃圾回收機制是java程序員必須要了解的知識,對於程序調優具有很大的幫助(同時也是大廠面試必問題)。

要了解垃圾回收機制,主要從三個方面:

(1)垃圾回收面向的對象是誰?

(2)垃圾回收演算法有哪些?

(3)垃圾收集器有哪些?每個收集器有什麼特點。

接下來一一講解清楚:

一、垃圾回收面向的對象

也就是字面意思, 垃圾 回收嘛,重要的是垃圾,那什麼對象是垃圾呢,簡單來說就是無用的或已死的對象。這樣又引申出來什麼對象是已死的,怎麼判斷對象是否已死?

判斷對象是否已死有兩種演算法和對象引用分類:

(1)引用計數演算法:

也是字面意思,通過給對象添加引用計數器,添加引用+1,反之-1。當引用為0的時候,此時對象就可判斷為無用的。

優點:實現簡單,效率高。

缺點:無法解決循環引用(就是A引用B,B也引用A的情況)的問題。

(2)根搜索演算法(也就是GC Roots):

通過一系列稱為GC Roots的對象,向下搜索,路徑為引用鏈,當某個對象無法向上搜索到GC Roots,也就是成為GC Roots不可達,則為無用對象。

如果一個對象是GC Roots不可達,則需要經過兩次標記才會進行回收,第一次標記的時候,會判斷是否需要執行finalize方法(沒必要執行的情況:沒實現finalize方法或者已經執行過)。如果需要執行finalize方法,則會放入一個回收隊列中,對於回收隊列中的對象,如果執行finalize方法之後,沒法將對象重新跟GC Roots進行關聯,則會進行回收。

很抽象,對吧,來一個明了的解釋?

比如手機壞了(不可達對象),有錢不在乎就直接拿去回收(這就是沒實現finalize方法),如果已經修過但是修不好了(已經執行過finalize方法),就直接拿去回收站回收掉。如果沒修過,就會拿去維修店(回收隊列)進行維修,實在維修不好了(執行了finalize方法,但是無法連上GC Roots),就會拿去回收站回收掉了。

那什麼對象可以成為GC Roots呢?

1>虛擬機棧中的引用對象

2>本地方法棧中Native方法引用的對象

2>方法區靜態屬性引用對象

3>方法區常量引用對象

(3)對象引用分類

1>強引用:例如實例一個對象,就是即使內存不夠用了,打死都不回收的那種。

2>軟引用:有用非必須對象,內存夠,則不進行回收,內存不夠,則回收。例如A借錢給B,當A還有錢的時候,B可以先不還,A沒錢了,B就必須還了。

3>弱引用:非必須對象,只能存活到下一次垃圾回收前。

4>虛引用:幽靈引用,必須跟引用隊列配合使用,目的是回收前收到系統通知。

下面是java的引用類型結構圖:

(1)軟引用示例

內存夠用的情況:

運行結果:

內存不夠用的情況:

運行結果:

(2)弱引用示例結果:

無論如何都會被回收

(3)虛引用示例:

運行結果:

解釋:為什麼2和5的輸出為null呢,如下

3為null是因為還沒有進行gc,所以對象還沒加入到引用隊列中,在gc後就加入到了引用隊列中,所以6有值。

這個虛引用在GC後會將對象放到引用隊列中,所以可以在對象回收後做相應的操作,判斷對象是否在引用隊列中,可以進行後置通知,類似spring aop的後置通知。

二、垃圾回收發生的區域

垃圾回收主要發生在堆內存裡面,而堆內存又細分為 年輕代 老年代 ,默認情況下年輕代和老年代比例為1:2,比如整個堆內存大小為3G,年輕代和老年代分別就是1G和2G,想要更改這個比例需要修改JVM參數-XX:NewRatio,

比如-XX:NewRatio=4,那老年代:年輕代=4:1。而年輕代又分為Eden區,S0(Survivor From)和S1(Survivor To)區,一般Eden:S0:S1=8:1:1,如果想要更改此比例,則修改JVM參數-XX:SurvivorRatio=4,此時就是Eden:S0:S1=4:1:1。

在年輕代發生GC稱為Young GC,老年代發生GC成為Full GC,Young GC比Full GC頻繁。

解析Young GC:

JVM啟動後,第一次GC,就會把Eden區存活的對象移入S0區;第二次GC就是Eden區和S0一起GC,此時會把存活的對象移入S1區,S0清空;第三次GC就是Eden區和S1區進行GC,會把存活的對象移入S0區,如此往復循環15次(默認),就會把存活的對象存入老年區。

類似與如果有三個桶,編號分別為1(1號桶內的沙子是源源不斷的,就像工地上。你們沒去工地搬過磚可能不知道,但是我真的去工地上搬過啊),2,3。1裡面裝有沙子,需要將沙子篩為細沙。首先將桶1內的沙子篩選一遍過後的放置於桶2,第二次篩選就會將桶1和桶2裡面的沙子一起篩,篩完之後放到桶3內,桶2清空。第三次篩選就會將桶1和桶3的沙子一起篩選,曬完放到桶2內,桶3清空。如此往復循環15次,桶2或桶3裡面的沙子就是合格的沙子,就需要放到備用桶內以待使用。

上述中桶1就是Eden區,桶2就是S0區,桶3就是S1區。

三、垃圾回收演算法

三種,分別是復制演算法,標記-清除演算法,標記-整理演算法。

(1)復制演算法。

其會將內存區域分成同樣大小的兩塊,一塊用來使用,另外一塊在GC的時候存放存活的對象,然後將使用的一塊清除。如此循環往復。

適用於新生代。

優點:沒有內存碎片,缺點:只能使用一般的內存。

(2)標記-清除演算法。

使用所有內存區域,在GC的時候會將需要回收的內存區域先進行標記,然後同意回收。

適用於老年代。

缺點:產生大量內存碎片,會直接導致大對象無法分配內存。

(3)標記-整理演算法。

使用所有內存區域,在GC的時候會先將需要回收的內存區域進行標記,然後將存活對象忘一邊移動,最後將清理掉邊界以外的所有內存。

適用於老年代。

四、GC日誌查看

利用JVM參數-XX:+PrintGCDetails就可以在GC的時候列印出GC日誌。

年輕代GC日誌:

老年代GC日誌:

五、垃圾收集器

主要有四類收集器以及七大收集器

四類:

(1)Serial:單線程收集器,阻塞工作線程,它一工作,全部都得停下。

(2)Paralle:Serial的多線程版本,也是阻塞工作線程

(3)CMS(ConcMarkSweep):並行垃圾收集器,可以和工作線程一起工作。

(4)G1:將堆分成大小一致的區域,然後並發的對其進行垃圾回收。

怎麼查看默認的收集器呢?

用JVM參數-XX:+PrintCommandLineFlags,運行之後會輸出如下參數。可以看到,jdk1.8默認是Parallel收集器。

七大收集器:

(1)Serial:串列垃圾收集器,單線程收集器。用於新生代。用JVM參數-XX:+UseSerialGC開啟,開啟後Young區用Serial(底層復制演算法),Old區用Serial Old(Serial的老年代版本,底層是標記整理演算法)。

(2)ParNew:用於新生代,並行收集器。就是Serial的多線程版本。用JVM參數-XX:+UseParNewGC,young:parnew,復制演算法。Old:serialOld,標記整理演算法。-XX:ParallecGCThreads限制線程回收數量,默認跟cpu數目一樣。只是新生代用並行,老年代用串列。

(3)Parallel Scavenge:並行回收收集器。用JVM參數-XX:+UseParallelGC開啟,young:parallel scavenge(底層是復制演算法),old:parallel old(parallel的老年代版本,底層是標記整理),新生代老年代都用並行回收器。

這個收集器有兩個優點:

可控的吞吐量 :就是工作線程工作90%的時間,回收線程工作10%的時間,即是說有90%的吞吐量。

自適應調節策略 :會動態調節參數以獲取最短的停頓時間。

(4)Parallel Old:Parallel Scavenge的老年代版本,用的是標記整理演算法。用JVM參數-XX:+UseParallelOldGC開啟,新生代用Parallel Scavenge,老年代用Parallel Old

(5)CMS(ConcMarkSweep):並發標記清除。 底層是標記清除演算法,所以會產生內存碎片,同時也會耗cpu。 以獲取最短回收停頓時間為目標。-XX:+UseConcMarkSweep,新生代用ParNew,老年代用CMS。CMS必須在堆內存用完之前進行清除,否則會失敗,這時會調用SerialOld後備收集器。

初始標記和重新標記都會停止工作線程,並發標記和並發清除會跟工作線程一起工作。

(6)SerialOld:老年代串列收集器(以後Hotspot虛擬機會直接移除掉)。

(7)G1:G1垃圾收集器,演算法是標記整理,不會產生內存碎片。橫跨新生代老年代。實現盡量高吞吐量,滿足回收停頓時間更短。

G1可以精確控制垃圾收集的停頓時間,用JVM參數-XX:MaxGCPauseMillis=n,n為停頓時間,單位為毫秒。

區域化內存劃片Region,會把整個堆劃分成同樣大小的區域塊(1MB~32MB),最多2048個內存區域塊,所以能支持的最大內存為32*2048=65535MB,約為64G。

上圖是收集前和收集後的對比,有些對象很大,分割之後就是連續的區域,也即是上圖的Humongous。

上述理論可能有點乏味,下圖很清晰明了(某度找的)。

下面來一張整個垃圾回收機制的思維導圖(太大,分成兩部分)。

=======================================================

我是Liusy,一個喜歡健身的程序猿。

歡迎關注【Liusy01】,一起交流Java技術及健身,獲取更多干貨。

『陸』 java中垃圾回收機制的原理是什麼

  1. GC的工作原理:引用計數,標記復制"引用計數"是一種簡單但速度很慢的垃圾回收技術.所有對象都有一個引用計數器,當有引用連接時計數器加1,當引用離開作用域時或者被置於NULL時,計數器-1,垃圾回收器會在所有包含對象引用的列表上進行遍歷,當發現某個對象的引用計數為0時,就釋放佔用的空間."標記復制"的運行機制,垃圾回收器遍歷包含所有引用的列表,當發現存活的對象引用時做上標記,這樣當遍歷完所有對象引用並做上標記的時候,執行垃圾回收,將沒有標記的對象堆空間釋放.

  2. 垃圾回收機制的優點:Java的垃圾回收機制使得java程序員不用擔心內存空間的分配,減少了內存溢出.但同時也犧牲了一定的性能.

『柒』 JAVA垃圾收集的演算法是怎麼樣的

Java語言規范沒有明確地說明JVM使用哪種垃圾回收演算法,但是任何一種垃圾收集演算法一般要做2件基本的事情:(1)發現無用信息對象;(2)回收被無用對象佔用的內存空間,使該空間可被程序再次使用。 (課課家教育)

大多數垃圾回收演算法使用了根集(root set)這個概念;所謂根集就量正在執行的Java程序可以訪問的引用變數的集合(包括局部變數、參數、類變數),程序可以使用引用變數訪問對象的屬性和調用對象的方法。垃圾收集首選需要確定從根開始哪些是可達的和哪些是不可達的,從根集可達的對象都是活動對象,它們不能作為垃圾被回收,這也包括從根集間接可達的對象。而根集通過任意路徑不可達的對象符合垃圾收集的條件,應該被回收。下面介紹幾個常用的演算法。

1、 引用計數法(Reference Counting Collector)

引用計數法是唯一沒有使用根集的垃圾回收的法,該演算法使用引用計數器來區分存活對象和不再使用的對象。一般來說,堆中的每個對象對應一個引用計數器。當每一次創建一個對象並賦給一個變數時,引用計數器置為1。當對象被賦給任意變數時,引用計數器每次加1當對象出了作用域後(該對象丟棄不再使用),引用計數器減1,一旦引用計數器為0,對象就滿足了垃圾收集的條件。

基於引用計數器的垃圾收集器運行較快,不會長時間中斷程序執行,適宜地必須 實時運行的程序。但引用計數器增加了程序執行的開銷,因為每次對象賦給新的變數,計數器加1,而每次現有對象出了作用域生,計數器減1。

2、tracing演算法(Tracing Collector)

tracing演算法是為了解決引用計數法的問題而提出,它使用了根集的概念。基於tracing演算法的垃圾收集器從根集開始掃描,識別出哪些對象可達,哪些對象不可達,並用某種方式標記可達對象,例如對每個可達對象設置一個或多個位。在掃描識別過程中,基於tracing演算法的垃圾收集也稱為標記和清除(mark-and-sweep)垃圾收集器.

3、compacting演算法(Compacting Collector)

為了解決堆碎片問題,基於tracing的垃圾回收吸收了Compacting演算法的思想,在清除的過程中,演算法將所有的對象移到堆的一端,堆的另一端就變成了一個相鄰的空閑內存區,收集器會對它移動的所有對象的所有引用進行更新,使得這些引用在新的位置能識別原來 的對象。在基於Compacting演算法的收集器的實現中,一般增加句柄和句柄表。

4、ing演算法(Coping Collector)

該演算法的提出是為了克服句柄的開銷和解決堆碎片的垃圾回收。它開始時把堆分成 一個對象 面和多個空閑面, 程序從對象面為對象分配空間,當對象滿了,基於coping演算法的垃圾 收集就從根集中掃描活動對象,並將每個 活動對象復制到空閑面(使得活動對象所佔的內存之間沒有空閑洞),這樣空閑面變成了對象面,原來的對象面變成了空閑面,程序會在新的對象面中分配內存。

一種典型的基於coping演算法的垃圾回收是stop-and-演算法,它將堆分成對象面和空閑區域面,在對象面與空閑區域面的切換過程中,程序暫停執行。

5、generation演算法(Generational Collector)

stop-and-垃圾收集器的一個缺陷是收集器必須復制所有的活動對象,這增加了程序等待時間,這是coping演算法低效的原因。在程序設計中有這樣的規律:多數對象存在的時間比較短,少數的存在時間比較長。因此,generation演算法將堆分成兩個或多個,每個子堆作為對象的一代(generation)。由於多數對象存在的時間比較短,隨著程序丟棄不使用的對象,垃圾收集器將從最年輕的子堆中收集這些對象。在分代式的垃圾收集器運行後,上次運行存活下來的對象移到下一最高代的子堆中,由於老一代的子堆不會經常被回收,因而節省了時間。

6、adaptive演算法(Adaptive Collector)

在特定的情況下,一些垃圾收集演算法會優於其它演算法。基於Adaptive演算法的垃圾收集器就是監控當前堆的使用情況,並將選擇適當演算法的垃圾收集器。

『捌』 JAVA垃圾回收的工作原理是什麼

Java虛擬機採取了一種自適應的垃圾回收技術。

閱讀全文

與垃圾收集java相關的資料

熱點內容
唯美動作愛情片 瀏覽:316
表情廣場app怎麼自己製作 瀏覽:249
看片著名網站 瀏覽:485
五十年代台灣電影 瀏覽:356
對單片機的基本認識 瀏覽:172
app公測版是什麼意思 瀏覽:786
安卓光遇配置不夠怎麼玩 瀏覽:761
男主叫強衰的是什麼電影 瀏覽:18
男主叫沈浪的都市小說 瀏覽:505
看電視的免費官網 瀏覽:407
怎麼共享伺服器賬套 瀏覽:735
星空衛視恐怖片 瀏覽:659
雞蛋加密封袋做法 瀏覽:540
有個女孩打檯球的叫什麼電影 瀏覽:874
虐戀之家是什麼app 瀏覽:245
鬼龕 又名 鬼屋 瀏覽:395
java截取中文字元 瀏覽:278
{"dc":"zdha26"} 瀏覽:814
張岱pdf 瀏覽:866
51單片機和快閃記憶體晶元的區別 瀏覽:314