主頁 > 後端開發 > 變禿了,也變強了!爆肝吐血整理出的超硬核JVM筆記分享!

變禿了,也變強了!爆肝吐血整理出的超硬核JVM筆記分享!

2020-11-24 19:15:10 後端開發

寫在前面

最近,一直有小伙伴讓我整理下關于JVM的知識,經過十幾天的收集與整理,初版算是整理出來了,希望對大家有所幫助,

記得點贊收藏加關注哦 ,需要下載PDF版本和更多知識點、面試題的朋友可以點一點下方鏈接免費領取

鏈接:點這里!!! 799215493 暗號:CSDN

在這里插入圖片描述

JDK 是什么?

JDK 是用于支持 Java 程式開發的最小環境,

  1. Java 程式設計語言
  2. Java 虛擬機
  3. Java API類別庫

JRE 是什么?

JRE 是支持 Java 程式運行的標準環境,

  1. Java SE API 子集
  2. Java 虛擬機

Java歷史版本的特性?

Java Version SE 5.0

  • 引入泛型;
  • 增強回圈,可以使用迭代方式;
  • 自動裝箱與自動拆箱;
  • 型別安全的列舉;
  • 可變引數;
  • 靜態引入;
  • 元資料(注解);
  • 引入Instrumentation,

Java Version SE 6

  • 支持腳本語言;
  • 引入JDBC 4.0 API;
  • 引入Java Compiler API;
  • 可插拔注解;
  • 增加對Native PKI(Public Key Infrastructure)、Java GSS(Generic Security Service)、Kerberos和LDAP(Lightweight Directory Access Protocol)的支持;
  • 繼承Web Services;
  • 做了很多優化,

Java Version SE 7

  • switch陳述句塊中允許以字串作為分支條件;
  • 在創建泛型物件時應用型別推斷;
  • 在一個陳述句塊中捕獲多種例外;
  • 支持動態語言;
  • 支持try-with-resources;
  • 引入Java NIO.2開發包;
  • 數值型別可以用2進制字串表示,并且可以在字串表示中添加下劃線;
  • 鉆石型語法;
  • null值的自動處理,

Java 8

  • 函式式介面
  • Lambda運算式
  • Stream API
  • 介面的增強
  • 時間日期增強API
  • 重復注解與型別注解
  • 默認方法與靜態方法
  • Optional 容器類

運行時資料區域包括哪些?

  1. 程式計數器
  2. Java 虛擬機堆疊
  3. 本地方法堆疊
  4. Java 堆
  5. 方法區
  6. 運行時常量池
  7. 直接記憶體

程式計數器(執行緒私有)

程式計數器(Program Counter Register)是一塊較小的記憶體空間,可以看作是當前執行緒所執行位元組碼的行號指示器,分支、回圈、跳轉、例外處理、執行緒恢復等基礎功能都需要依賴這個計數器完成,

由于 Java 虛擬機的多執行緒是通過執行緒輪流切換并分配處理器執行時間的方式實作的,為了執行緒切換后能恢復到正確的執行位置,每條執行緒都需要一個獨立的程式計數器,各執行緒之間的計數器互不影響,獨立存盤,

  1. 如果執行緒正在執行的是一個 Java 方法,計數器記錄的是正在執行的虛擬機位元組碼指令的地址;
  2. 如果正在執行的是 Native 方法,這個計數器的值為空,

程式計數器是唯一一個沒有規定任何 OutOfMemoryError 的區域,

Java 虛擬機堆疊(執行緒私有)

Java 虛擬機堆疊(Java Virtual Machine Stacks)是執行緒私有的,生命周期與執行緒相同,
虛擬機堆疊描述的是 Java 方法執行的記憶體模型:每個方法被執行的時候都會創建一個堆疊幀(Stack Frame),存盤

  1. 區域變數表
  2. 操作堆疊
  3. 動態鏈接
  4. 方法出口

每一個方法被呼叫到執行完成的程序,就對應著一個堆疊幀在虛擬機堆疊中從入堆疊到出堆疊的程序,

這個區域有兩種例外情況:

  1. StackOverflowError:執行緒請求的堆疊深度大于虛擬機所允許的深度
  2. OutOfMemoryError:虛擬機堆疊擴展到無法申請足夠的記憶體時

本地方法堆疊(執行緒私有)

虛擬機堆疊為虛擬機執行 Java 方法(位元組碼)服務,

本地方法堆疊(Native Method Stacks)為虛擬機使用到的 Native 方法服務,

Java 堆(執行緒共享)

Java 堆(Java Heap)是 Java 虛擬機中記憶體最大的一塊,Java 堆在虛擬機啟動時創建,被所有執行緒共享,

作用:存放物件實體,垃圾收集器主要管理的就是 Java 堆,Java 堆在物理上可以不連續,只要邏輯上連續即可,

方法區(執行緒共享)

方法區(Method Area)被所有執行緒共享,用于存盤已被虛擬機加載的類資訊、常量、靜態變數、即時編譯器編譯后的代碼等資料,

和 Java 堆一樣,不需要連續的記憶體,可以選擇固定的大小,更可以選擇不實作垃圾收集,

運行時常量池

運行時常量池(Runtime Constant Pool)是方法區的一部分,保存 Class 檔案中的符號參考、翻譯出來的直接參考,運行時常量池可以在運行期間將新的常量放入池中,

如何判斷物件是否“死去”?

  1. 參考計數法
  2. 根搜索演算法

什么是參考計數法?

給物件添加一個參考計數器,每當有一個地方參考它,計數器就+1,;當參考失效時,計數器就-1;任何時刻計數器都為0的物件就是不能再被使用的,

參考計數法的缺點?

很難解決物件之間的回圈參考問題,

Java 的4種參考方式?

在 JDK 1.2 之后,Java 對參考的概念進行了擴充,將參考分為

  1. 強參考 Strong Reference
  2. 軟參考 Soft Reference
  3. 弱參考 Weak Reference
  4. 虛參考 Phantom Reference

強參考

Object obj =  new  Object();

代碼中普遍存在的,像上述的參考,只要強參考還在,垃圾收集器永遠不會回收掉被參考的物件,

軟參考

用來描述一些還有用,但并非必須的物件,軟參考所關聯的物件,有在系統將要發生記憶體溢位例外之前,將會把這些物件列進回收范圍,并進行第二次回收,如果這次回識訓是沒有足夠的記憶體,才會拋出記憶體例外,提供了 SoftReference 類實作軟參考,

弱參考

描述非必須的物件,強度比軟參考更弱一些,被弱參考關聯的物件,只能生存到下一次垃圾收集發生前,當垃圾收集器作業時,無論當前記憶體是否足夠,都會回收掉只被弱參考關聯的物件,提供了 WeakReference 類來實作弱參考,

虛參考

一個物件是否有虛參考,完全不會對其生存時間夠成影響,也無法通過虛參考來取得一個物件實體,為一個物件關聯虛參考的唯一目的,就是希望在這個物件被收集器回收時,收到一個系統通知,提供了 PhantomReference 類來實作虛參考,

有哪些垃圾收集演算法?

  1. 標記-清除演算法
  2. 復制演算法
  3. 標記-整理演算法
  4. 分代收集演算法

分代收集演算法

根據物件的存活周期,將記憶體劃分為幾塊,一般是把 Java 堆分為新生代和老年代,這樣就可以根據各個年代的特點,采用最適當的收集演算法,

  • 新生代:每次垃圾收集時會有大批物件死去,只有少量存活,所以選擇復制演算法,只需要少量存活物件的復制成本就可以完成收集,
  • 老年代:物件存活率高、沒有額外空間對它進行分配擔保,必須使用“標記-清理”或“標記-整理”演算法進行回收,

記得點贊收藏加關注哦 ,需要下載PDF版本和更多知識點、面試題的朋友可以點一點下方鏈接免費領取

鏈接:點這里!!! 799215493 暗號:CSDN

Minor GC 和 Full GC有什么區別?

Minor GC:新生代 GC,指發生在新生代的垃圾收集動作,因為 Java 物件大多死亡頻繁,所以 Minor GC 非常頻繁,一般回收速度較快,

Full GC:老年代 GC,也叫 Major GC,速度一般比 Minor GC 慢 10 倍以上,

Java 記憶體

為什么要將堆記憶體磁區?

對于一個大型的系統,當創建的物件及方法變數比較多時,即堆記憶體中的物件比較多,如果逐一分析物件是否該回收,效率很低,磁區是為了進行模塊化管理,管理不同的物件及變數,以提高 JVM 的執行效率,

堆記憶體分為哪幾塊?

  1. Young Generation Space 新生區(也稱新生代)
  2. Tenure Generation Space養老區(也稱舊生代)
  3. Permanent Space 永久存盤區

分代收集演算法

記憶體分配有哪些原則?
  1. 物件優先分配在 Eden
  2. 大物件直接進入老年代
  3. 長期存活的物件將進入老年代
  4. 動態物件年齡判定
  5. 空間分配擔保
Young Generation Space (采用復制演算法)

主要用來存盤新創建的物件,記憶體較小,垃圾回收頻繁,這個區又分為三個區域:一個 Eden Space 和兩個 Survivor Space,

  • 當物件在堆創建時,將進入年輕代的Eden Space,
  • 垃圾回收器進行垃圾回收時,掃描Eden Space和A Suvivor Space,如果物件仍然存活,則復制到B Suvivor Space,如果B Suvivor Space已經滿,則復制 Old Gen
  • 掃描A Suvivor Space時,如果物件已經經過了幾次的掃描仍然存活,JVM認為其為一個Old物件,則將其移到Old Gen,
  • 掃描完畢后,JVM將Eden Space和A Suvivor Space清空,然后交換A和B的角色(即下次垃圾回收時會掃描Eden Space和B Suvivor Space,

Tenure Generation Space(采用標記-整理演算法)

主要用來存盤長時間被參考的物件,它里面存放的是經過幾次在 Young Generation Space 進行掃描判斷過仍存活的物件,記憶體較大,垃圾回收頻率較小,

Permanent Space

存盤不變的類定義、位元組碼和常量等,

類加載器

類加載器的作用是什么?

類加載器實作類的加載動作,同時用于確定一個類,對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立其在Java虛擬機中的唯一性,即使兩個類來源于同一個Class檔案,只要加載它們的類加載器不同,這兩個類就不相等,

類加載器有哪些?

  1. 啟動類加載器(Bootstrap ClassLoader):使用C++實作(僅限于HotSpot),是虛擬機自身的一部分,負責將存放在\lib目錄中的類別庫加載到虛擬機中,其無法被Java程式直接參考,
  2. 擴展類加載器(Extention ClassLoader)由ExtClassLoader實作,負責加載\lib\ext目錄中的所有類別庫,開發者可以直接使用,
  3. 應用程式類加載器(Application ClassLoader):由APPClassLoader實作,負責加載用戶類路徑(ClassPath)上所指定的類別庫,

類加載機制

什么是雙親委派模型?

雙親委派模型(Parents Delegation Model)要求除了頂層的啟動類加載器外,其余加載器都應當有自己的父類加載器,類加載器之間的父子關系,通過組合關系復用,

作業程序:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器完成,每個層次的類加載器都是如此,因此所有的加載請求最終都應該傳送到頂層的啟動類加載器中,只有到父加載器反饋自己無法完成這個加載請求(它的搜索范圍沒有找到所需的類)時,子加載器才會嘗試自己去加載,

為什么要使用雙親委派模型,組織類加載器之間的關系?

Java類隨著它的類加載器一起具備了一種帶優先級的層次關系,比如java.lang.Object,它存放在rt.jar中,無論哪個類加載器要加載這個類,最終都是委派給啟動類加載器進行加載,因此Object類在程式的各個類加載器環境中,都是同一個類,

如果沒有使用雙親委派模型,讓各個類加載器自己去加載,那么Java型別體系中最基礎的行為也得不到保障,應用程式會變得一片混亂,

什么是類加載機制?

Class檔案描述的各種資訊,都需要加載到虛擬機后才能運行,虛擬機把描述類的資料從Class檔案加載到記憶體,并對資料進行校驗、轉換決議和初始化,最終形成可以被虛擬機直接使用的Java型別,這就是虛擬機的類加載機制,

虛擬機和物理機的區別是什么?

這兩種機器都有代碼執行的能力,但是:

  • 物理機的執行引擎是直接建立在處理器、硬體、指令集和作業系統層面的,
  • 虛擬機的執行引擎是自己實作的,因此可以自行制定指令集和執行引擎的結構體系,并且能夠執行那些不被硬體直接支持的指令集格式,

Java 方法呼叫

什么是方法呼叫?

方法呼叫唯一的任務是確定被呼叫方法的版本(呼叫哪個方法),暫時還不涉及方法內部的具體運行程序,

Java的方法呼叫,有什么特殊之處?

Class檔案的編譯程序不包含傳統編譯的連接步驟,一切方法呼叫在Class檔案里面存盤的都只是符號參考,而不是方法在實際運行時記憶體布局中的入口地址,這使得Java有強大的動態擴展能力,但使Java方法的呼叫程序變得相對復雜,需要在類加載期間甚至到運行時才能確定目標方法的直接參考,

Java虛擬機呼叫位元組碼指令有哪些?

  • invokestatic:呼叫靜態方法
  • invokespecial:呼叫實體構造器方法、私有方法和父類方法
  • invokevirtual:呼叫所有的虛方法
  • invokeinterface:呼叫介面方法

虛擬機是如何執行方法里面的位元組碼指令的?

解釋執行(通過解釋器執行)
編譯執行(通過即時編譯器產生本地代碼)

解釋執行

當主流的虛擬機中都包含了即時編譯器后,Class檔案中的代碼到底會被解釋執行還是編譯執行,只有虛擬機自己才能準確判斷,

Javac編譯器完成了程式代碼經過詞法分析、語法分析到抽象語法樹,再遍歷語法樹生成線性的位元組碼指令流的程序,因為這一動作是在Java虛擬機之外進行的,而解釋器在虛擬機的內部,所以Java程式的編譯是半獨立的實作,

最后

由于篇幅有限,這里只展示一部分,需要完整版的朋友可以點一點下方鏈接免費領取~

在這里也為大家整理了各個知識點模塊整理檔案(微服務、資料庫、mysql、jvm、Redis等都有)和更多大廠面試真題,有需要的朋友可以點一點下方鏈接免費領取

鏈接:點這里!!! 799215493 暗號:CSDN

在這里插入圖片描述
在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/226840.html

標籤:java

上一篇:想拿到10k-40k的offer,這些技能必不可少!作為程式員的你了解嗎?

下一篇:左手位元組,右手阿里,我是如何通阿里架構師的java面試檔案,拿到多家大廠offer的

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more