垃圾收集器G1ZGC詳解

G1收集器(-XX:+UseG1GC)

在這里插入圖片描述
G1 把堆劃分為許多大小相同的 Region(默認 1~32 MB,一個堆通常包含上千個 Region,JVM目標是不超過2048個Region(JVM源碼里TARGET_REGION_NUMBER 定義))
不再是傳統的 Eden、Survivor、Old 靜態分代模型,而是用邏輯分區標記 Region 類型,采用復制算法針對每個區域進行垃圾回收,同樣也支持動態的調整內存大小。

分代

  • 年輕代 Region(Eden + Survivor)
  • 老年代 Region
  • 大對象 Region(Humongous)

每個Region的屬性可動態調整

一般Region大小等于堆大小除以2048,比如堆大小為4096M,則Region大小為2M,當然也可以用參數"-XX:G1HeapRegionSize"手動指定Region大小,但是推薦默認的計算方式。

默認年輕代對堆內存的占比是5%,如果堆大小為4096M,那么年輕代占據200MB左右的內存,對應大概是100個Region,可以通過“-XX:G1NewSizePercent”設置新生代初始占比,在系統運行中,JVM會不停的給年輕代增加更多的Region,但是最多新生代的占比不會超過60%,可以通過“-XX:G1MaxNewSizePercent”調整。

年輕代中的Eden和Survivor比例也是默認8:1:1

回收步驟

G1收集器一次GC(主要值Mixed GC)的運作過程大致分為以下幾個步驟:

  • 初始標記(initial mark,STW):暫停所有的其他線程,并記錄下gc roots直接能引用的對象,速度很快
  • 并發標記(Concurrent Marking):同CMS的并發標記
  • 最終標記(Remark,STW):同CMS的重新標記
  • 篩選回收(Cleanup,STW):篩選回收階段首先對各個Region的回收價值和成本進行排序,根據用戶所期望的GC停頓STW時間(可以用JVM參數-XX:MaxGCPauseMillis指定)來制定回收計劃

老年代此時有1000個Region都滿了,但是因為根據預期停頓時間,本次垃圾回收可能只能停頓200毫秒,那么通過之前回收成本計算得知,可能回收其中800個Region剛好需要200ms,那么就只會回收800個Region(Collection Set,要回收的集合),盡量把GC導致的停頓時間控制在我們指定的范圍內。

不管是年輕代或是老年代,回收算法主要用的是復制算法,將一個region中的存活對象復制到另一個region中,這種不會像CMS那樣回收完因為有很多內存碎片還需要整理一次,G1采用復制算法回收幾乎不會有太多內存碎片(CMS回收階段是跟用戶線程一起并發執行的,G1因為內部實現太復雜暫時沒實現并發回收)
在這里插入圖片描述**G1收集器在后臺維護了一個優先列表,每次根據允許的收集時間,優先選擇回收價值最大的Region(這也就是它的名字Garbage-First的由來)。一個Region花200ms能回收10M垃圾,另外一個Region花50ms能回收20M垃圾,在回收時間有限情況下,G1會優先選擇后面這個Region回收。**這種使用Region劃分內存空間以及有優先級的區域回收方式,保證了G1收集器在有限時間內可以盡可能高的收集效率。

大對象處理

不同的是對大對象的處理,G1有專門分配大對象的Region叫Humongous區。在G1中,大對象的判定規則就是一個大對象超過了一個Region大小的50%,比如按照上面算的,每個Region是2M,只要一個大對象超過了1M,就會被放入Humongous中,而且一個大對象如果太大,可能會橫跨多個Region來存放。

Humongous區專門存放短期巨型對象,不用直接進老年代,可以節約老年代的空間,避免因為老年代空間不夠的GC開銷。

特點

  • 并行與并發:G1能充分利用CPU、多核環境下的硬件優勢,使用多個CPU(CPU或者CPU核心)來縮短Stop-The-World停頓時間。部分其他收集器原本需要停頓Java線程來執行GC動作,G1收集器仍然可以通過并發的方式讓java程序繼續執行。
  • 分代收集:雖然G1可以不需要其他收集器配合就能獨立管理整個GC堆,但是還是保留了分代的概念。
  • 空間整合:與CMS的“標記–清理”算法不同,G1從整體來看是基于“標記整理”算法實現的收集器;從局部上來看是基于“復制”算法實現的。
  • 可預測的停頓:這是G1相對于CMS的另一個大優勢,降低停頓時間是G1 和 CMS 共同的關注點,但G1
    除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為M毫秒的時間片段(通過參數"-XX:MaxGCPauseMillis"指定)內完成垃圾收集。

GC回收

Full GC的時候除了收集年輕代和老年代之外,也會將Humongous區一并回收。

  • Young GC(年輕代收集)
    回收年輕代中的 Eden 和 Survivor 區。G1會計算下現在Eden區回收大概要多久時間,如果回收時間遠遠小于參數 -XX:MaxGCPauseMillis 設定的值,那么增加年輕代的region,繼續給新對象存放,不會馬上做Young GC,直到下一次Eden區放滿,G1計算回收時間接近參數 -XX:MaxGCPauseMillis 設定的值,那么就會觸發Young GC

  • Mixed GC(混合回收)
    回收年輕代和部分老年代垃圾多的 Region。老年代的堆占有率達到參數(-XX:InitiatingHeapOccupancyPercent)設定的值則觸發,回收所有的Young和部分Old(根據期望的GC停頓時間確定old區垃圾收集的優先順序)以及大對象區,正常情況G1的垃圾收集是先做MixedGC,主要使用復制算法,需要把各個region中存活的對象拷貝到別的region里去,拷貝過程中如果發現沒有足夠的空region能夠承載拷貝對象就會觸發一次Full GC

  • Full GC
    停止系統程序,然后采用單線程進行標記、清理和壓縮整理,好空閑出來一批Region來供下一次MixedGC使用,這個過程是非常耗時的。(Shenandoah優化成多線程收集了)

G1收集器參數設置

-XX:+UseG1GC:使用G1收集器
-XX:ParallelGCThreads:指定GC工作的線程數量
-XX:G1HeapRegionSize:指定分區大小(1MB~32MB,且必須是2的N次冪),默認將整堆劃分為2048個分區
-XX:MaxGCPauseMillis:目標暫停時間(默認200ms)
-XX:G1NewSizePercent:新生代內存初始空間(默認整堆5%,值配置整數,默認就是百分比)
-XX:G1MaxNewSizePercent:新生代內存最大空間
-XX:TargetSurvivorRatio:Survivor區的填充容量(默認50%),Survivor區域里的一批對象(年齡1+年齡2+年齡n的多個年齡對象)總和超過了Survivor區域的50%,此時就會把年齡n(含)以上的對象都放入老年代
-XX:MaxTenuringThreshold:最大年齡閾值(默認15)
-XX:InitiatingHeapOccupancyPercent:老年代占用空間達到整堆內存閾值(默認45%),則執行新生代和老年代的混合收集(MixedGC),比如我們之前說的堆默認有2048個region,如果有接近1000個region都是老年代的region,則可能就要觸發MixedGC了
-XX:G1MixedGCLiveThresholdPercent(默認85%) region中的存活對象低于這個值時才會回收該region,如果超過這個值,存活對象過多,回收的的意義不大。
-XX:G1MixedGCCountTarget:在一次回收過程中指定做幾次篩選回收(默認8次),在最后一個篩選回收階段可以回收一會,然后暫停回收,恢復系統運行,一會再開始回收,這樣可以讓系統不至于單次停頓時間過長。
-XX:G1HeapWastePercent(默認5%): gc過程中空出來的region是否充足閾值,在混合回收的時候,對Region回收都是基于復制算法進行的,都是把要回收的Region里的存活對象放入其他Region,然后這個Region中的垃圾對象全部清理掉,這樣的話在回收過程就會不斷空出來新的Region,一旦空閑出來的Region數量達到了堆內存的5%,此時就會立即停止混合回收,意味著本次混合回收就結束了。

G1垃圾收集器優化建議

調節 -XX:MaxGCPauseMills 這個參數的值,在保證他的年輕代gc別太頻繁的同時,還得考慮每次gc過后的存活對象有多少,避免存活對象太多快速進入老年代,頻繁觸發mixed gc.

什么場景適合使用G1
50%以上的堆被存活對象占用
對象分配和晉升的速度變化非常大
垃圾回收時間特別長,超過1秒
8GB以上的堆內存(建議值)
停頓時間是500ms以內

ZGC收集器(-XX:+UseZGC)

在這里插入圖片描述
ZGC目標

  • 支持TB量級的堆。我們生產環境的硬盤還沒有上TB呢,這應該可以滿足未來十年內,所有JAVA應用的需求了吧。
  • 最大GC停頓時間不超10ms。目前一般線上環境運行良好的JAVA應用Minor GC停頓時間在10ms左右,Major GC一般都需要100ms以上(G1可以調節停頓時間,但是如果調的過低的話,反而會適得其反),之所以能做到這一點是因為它的停頓時間主要跟Root掃描有關,而Root數量和堆大小是沒有任何關系的。
  • 奠定未來GC特性的基礎。
  • 最糟糕的情況下吞吐量會降低15%。這都不是事,停頓時間足夠優秀。至于吞吐量,通過擴容分分鐘解決。

Oracle官方提到了它最大的優點是:它的停頓時間不會隨著堆的增大而增長!

不分代(暫時)
單代,即ZGC「沒有分代」。為什么ZGC就不分代呢?因為分代實現起來麻煩,作者就先實現出一個比較簡單可用的單代版本,后續會優化。

ZGC內存布局

ZGC收集器是一款基于Region內存布局的, 暫時不設分代的, 使用了讀屏障、 顏色指針等技術來實現可并發的標記-整理算法的, 以低延遲為首要目標的一款垃圾收集器。

  • 小型Region(Small Region) : 容量固定為2MB, 用于放置小于256KB的小對象。
  • 中型Region(Medium Region) : 容量固定為32MB, 用于放置大于等于256KB但小于4MB的對象。
  • 大型Region(Large Region) : 容量不固定, 可以動態變化, 但必須為2MB的整數倍, 用于放置4MB或以上的大對象。 每個大型Region中只會存放一個大對象雖然名字叫作“大型Region”, 但它的實際容量完全有可能小于中型Region, 最小容量可低至4MB。 大型Region在ZGC的實現中是不會被重分配, 因為復制一個大對象的代價非常高昂。

在這里插入圖片描述

ZGC針對NUMA深度優化

NUMA對應的有UMA,UMA即Uniform Memory Access Architecture,NUMA就是Non Uniform Memory Access Architecture。通過感知和優化內存分配、線程調度,盡量讓線程訪問本地節點內存,減少遠程訪問,提高性能和吞吐。
在這里插入圖片描述

ZGC運作過程

在這里插入圖片描述

  • 并發標記(Concurrent Mark):
    與G1一樣,并發標記是遍歷對象圖做可達性分析的階段,它的初始標記(Mark Start)和最終標記(Mark End)也會出現短暫的停頓,與G1不同的是,** ZGC的標記是在指針上而不是在對象上進行的, 標記階段會更新顏色指針中的Marked 0、 Marked 1標志位。**
  • 并發預備重分配(Concurrent Prepare for Relocate):
    根據特定的查詢條件統計得出本次收集過程要清理哪些Region,將這些Region組成重分配集(Relocation Set)。ZGC每次回收都會掃描所有的Region,用范圍更大的掃描成本換取省去G1中記憶集的維護成本。
  • 并發重分配(Concurrent Relocate):
    重分配是ZGC執行過程中的核心階段,這個過程要把重分配集中的存活對象復制到新的Region上,并為重分配集中的每個Region維護一個轉發表(Forward Table),記錄從舊對象到新對象的轉向關系。ZGC收集器能僅從引用上就明確得知一個對象是否處于重分配集之中,如果用戶線程此時并發訪問了位于重分配集中的對象,這次訪問將會被預置的內存屏障(讀屏障(見下面詳解))所截獲,然后立即根據Region上的轉發表記錄將訪問轉發到新復制的對象上,并同時修正更新該引用的值,使其直接指向新對象,ZGC將這種行為稱為指針的“自愈”(Self-Healing)能力。
  • 并發重映射(Concurrent Remap):
    重映射所做的就是修正整個堆中指向重分配集中舊對象的所有引用,但是ZGC中對象引用存在“自愈”功能,所以這個重映射操作并不是很迫切。ZGC把并發重映射階段要做的工作合并到了下一次垃圾收集循環中的并發標記階段里完成。一旦所有指針都被修正之后, 原來記錄新舊對象關系的轉發表就可以釋放掉了。

顏色指針
以前的垃圾回收器的GC信息都保存在對象頭中,而ZGC的GC信息保存在指針中。
在這里插入圖片描述
每個對象有一個64位指針,這64位被分為:

  • 18位:預留給以后使用;
  • 1位:Finalizable標識,此位與并發引用處理有關,它表示這個對象只能通過finalizer才能訪問;
  • 1位:Remapped標識,設置此位的值后,對象未指向relocation set中(relocation
    set表示需要GC的Region集合);
  • 1位:Marked1標識;
  • 1位:Marked0標識,和上面的Marked1都是標記對象用于輔助GC;
  • 42位:對象的地址(所以它可以支持2^42=4T內存)

** 為什么有2個mark標記?**
每一個GC周期開始時,會交換使用的標記位,使上次GC周期中修正的已標記狀態失效,所有引用都變成未標記。
GC周期1:使用mark0, 則周期結束所有引用mark標記都會成為01。
GC周期2:使用mark1, 則期待的mark標記10,所有引用都能被重新標記。

對配置ZGC后對象指針分析我們可知,對象指針必須是64位,那么ZGC就無法支持32位操作系統,同樣的也就無法支持壓縮指針了(CompressedOops,壓縮指針也是32位)。

** 顏色指針的三大優勢:**

  1. 一旦某個Region的存活對象被移走之后,這個Region立即就能夠被釋放和重用掉,而不必等待整個堆中所有指向該Region的引用都被修正后才能清理,這使得理論上只要還有一個空閑Region,ZGC就能完成收集。因為還有轉發表維護轉發關系
  2. 顏色指針可以大幅減少在垃圾收集過程中內存屏障的使用數量,ZGC只使用了讀屏障。
  3. 顏色指針具備強大的擴展性,它可以作為一種可擴展的存儲結構用來記錄更多與對象標記、重定位過程相關的數據,以便日后進一步提高性能。

讀屏障

之前的GC都是采用Write Barrier,這次ZGC采用了完全不同的方案讀屏障,這個是ZGC一個非常重要的特性。
在標記和移動對象的階段,每次「從堆里對象的引用類型中讀取一個指針」的時候,都需要加上一個Load Barriers。

判斷對象是Bad Color還是Good Color的依據是什么呢?就是根據上一段提到的Colored Pointers的4個顏色位。當加上讀屏障時,根據對象指針中這4位的信息,就能知道當前對象是Bad/Good Color了。

低42位指針可以支持4T內存,那么能否通過預約更多位給對象地址來達到支持更大內存的目的呢?答案肯定是不可以。因為目前主板地址總線最寬只有48bit,4位是顏色位,就只剩44位了,所以受限于目前的硬件,ZGC最大只能支持16T的內存,JDK13就把最大支持堆內存從4T擴大到了16T。

ZGC存在的問題

ZGC最大的問題是浮動垃圾。ZGC的停頓時間是在10ms以下,但是ZGC的執行時間還是遠遠大于這個時間的。假如ZGC全過程需要執行10分鐘,在這個期間由于對象分配速率很高,將創建大量的新對象,這些對象很難進入當次GC,所以只能在下次GC的時候進行回收,這些只能等到下次GC才能回收的對象就是浮動垃圾。

解決方案
目前唯一可行的辦法是增加堆容量,為程序爭取更多緩沖時間,但這只能暫時緩解問題。要從根本上解決,必須引入分代收集機制:將新創建的對象集中存放在特定區域,并針對該區域實施更頻繁、更高效的回收策略。

ZGC參數設置

啟用ZGC比較簡單,設置JVM參數即可:-XX:+UnlockExperimentalVMOptions 「-XX:+UseZGC」。
在這里插入圖片描述

ZGC觸發時機

ZGC目前有4中機制觸發GC:

  • 定時觸發,默認為不使用,可通過ZCollectionInterval參數配置。
  • 預熱觸發,最多三次,在堆內存達到10%、20%、30%時觸發,主要時統計GC時間,為其他GC機制使用。
  • 分配速率,基于正態分布統計,計算內存99.9%可能的最大分配速率,以及此速率下內存將要耗盡的時間點,在耗盡之前觸發GC(耗盡時間 - 一次GC最大持續時間 - 一次GC檢測周期時間)。
  • 主動觸發,(默認開啟,可通過ZProactive參數配置) 距上次GC堆內存增長10%,或超過5分鐘時,對比距上次GC的間隔時間跟(49 * 一次GC的最大持續時間),超過則觸發。

選擇垃圾收集器

  1. 優先調整堆的大小讓服務器自己來選擇
  2. 如果內存小于100M,使用串行收集器
  3. 如果是單核,并且沒有停頓時間的要求,串行或JVM自己選擇
  4. 如果允許停頓時間超過1秒,選擇并行或者JVM自己選
  5. 如果響應時間最重要,并且不能超過1秒,使用并發收集器
  6. 4G以下可以用parallel,4-8G可以用ParNew+CMS,8G以上可以用G1,幾百G以上用ZGC
    下圖有連線的可以搭配使用

在這里插入圖片描述
JDK 1.8默認使用 Parallel和Parallel Old
JDK 1.9默認使用 G1

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88413.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88413.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88413.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Bootstrap 5學習教程,從入門到精通,Bootstrap 5 彈出框(Popovers) 語法知識點及案例(22)

Bootstrap 5 彈出框(Popovers) 語法知識點及案例 一、彈出框基本概念 彈出框(Popovers)是Bootstrap提供的一個小型覆蓋層組件,用于顯示額外的信息,當用戶點擊某個元素時出現,再次點擊時消失。 二、彈出框基本語法知識點 1. 必需屬性 dat…

輕巧靈動,智啟未來 ——Kinova Gen3 Lite 機器人輕松解鎖各行業自動化新姿勢

近年來,Kinova Gen3 Lite 機器人憑借其卓越的性能、靈活的應用能力以及出色的性價比,在全球范圍內掀起了一股熱銷狂潮。無論是科研機構、高校實驗室,還是工業制造企業,都對它青睞有加。其銷量持續攀升,市場占有率不斷擴…

STM32 實現PID

&#x1f9f1; 一、PID核心模塊&#xff08;模塊化設計&#xff09; 頭文件 pid_controller.h #pragma once #include <stdint.h>typedef struct {// 可調參數float Kp, Ki, Kd; // PID系數float output_min; // 輸出下限float output_max; // 輸出上…

基于MATLAB的BP神經網絡回歸模型在空氣質量預測中的應用

說明&#xff1a;這是一個機器學習實戰項目&#xff08;附帶數據代碼文檔&#xff09;&#xff0c;如需數據代碼文檔可以直接到文章最后關注獲取。 1.項目背景 隨著城市化進程的加快和工業化的不斷發展&#xff0c;空氣質量問題日益受到廣泛關注。空氣中污染物如PM2.5、PM10、…

Linux docker拉取鏡像報錯解決

1、錯誤提示&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection 主要原因就是docker源不正確&#xff0c;需要配置一下。 2、報錯如下&#xff1a; 3、解決辦法&#x…

stm32week17+18+19+20

stm32學習 十二.串口 5.USART的HAL庫用法 USART/UART異步通信配置步驟&#xff1a; 配置串口工作參數&#xff1a;HAL_UART_Init();串口底層初始化&#xff1a;HAL_UART_MspInit();開啟串口異步接收中斷&#xff1a;HAL_UART_Receive_IT();設置優先級&#xff0c;使能中斷&…

14.Linux Docker

## Linux系統優化一般情況&#xff0c;我們都會使用Linux來進行MySQL的安裝和部署&#xff0c;Linux系統在使用的時候&#xff0c;也需要進行相關的配置&#xff0c;以提高MySQL的使用性能&#xff0c;這里列舉以下幾點&#xff1a;避免使用Swap交換分區&#xff0c;因為交換時…

智能體平臺的商業前景與競爭格局分析:金融與企業市場的機遇與挑戰

一、金融機構與企業部署第三方智能體平臺&#xff0c;這條路靠譜嗎&#xff1f; 1. 需求背景 金融機構和大中小企業普遍面臨數字化轉型、降本增效、智能服務升級等需求。智能體&#xff08;Agent/AI Agent&#xff09;平臺能幫助企業快速構建客服、風控、營銷、數據分析等多種…

數據結構篇-二分圖

定義示例應用 定義 一個圖是二分圖&#xff1b;一個圖具有二著色性&#xff1b;一個圖不包含任何奇數長度的環&#xff1b; 實現 /*** Program 18.6 Two-colorability* ------------------------------------------------------------------------------------------------…

50. Pow(x, n)快速冪算法

實現 pow(x, n) &#xff0c;即計算 x 的整數 n 次冪函數&#xff08;即&#xff0c;xn &#xff09;。此函數應將 x 作為浮點數&#xff08;意味著它可以是十進制數&#xff09;和 n 作為整數&#xff08;可以是正數、負數或零&#xff09;一起使用。 快速冪&#xff08;Expo…

打造絲滑的Android應用:LiveData完全教程

為什么你需要LiveData&#xff1f; 在Android開發中&#xff0c;數據的動態更新一直是個讓人頭疼的問題。想象一下&#xff1a;你的界面需要實時顯示用戶的余額變化&#xff0c;或者一個聊天應用的未讀消息數得隨時刷新。過去&#xff0c;我們可能會用Handler、手動監聽器&…

vue3 el-table 根據字段值 改變整行字體顏色

在 Vue 3 中使用 Element Plus 的 el-table 組件時&#xff0c;如果你想根據某一列的字段值來改變整行的字體顏色&#xff0c;你可以通過使用自定義的 row-class-name 屬性或者通過插槽&#xff08;slot&#xff09;的方式來達到目的。以下是兩種常見的方法&#xff1a; 方法一…

Linux的全新網絡管理命令行工具——nmcli

一、nmcli簡介 1.1、NetworkManager簡介 1.1.1、NetworkManager介紹 在紅帽系的Linux中&#xff0c;默認的網絡服務是由NetworkManager提供的&#xff08;其主要是一個可以進行動態網絡配置和控制的守護進程&#xff09;。 使用NetworkManager的優點 序號使用NetworkManager的優…

C++基礎之智能指針

一、概念 堆內存對象需要手動使用delete銷毀&#xff0c;如果沒有使用delete銷毀就會造成內存泄漏。 所以C在ISO98標準中引入了智能指針的概念&#xff0c;并在ISO11中趨于完善。 使用智能指針可以讓堆內存對象具有棧內存對象的特點&#xff0c;原理是給需要手動回收的內內存對…

python3虛擬機線程切換過程

python實現了自己的多線程&#xff0c;為了保證線程安全&#xff0c;引入了全局解釋器鎖GIL&#xff0c;只有拿到GIL的線程才能執行&#xff0c;所以在python中同一時刻只能有一個線程在運行&#xff0c;python多線程無法發揮多核處理器的威力&#xff0c;《python源碼剖析》中…

PYTHON從入門到實踐5-列表操作

# 【1】列表是可變的&#xff0c;可以修改、追加、刪除 import randomclass Friend(object):def __init__(self, name, age):self.name nameself.age ageif __name__ __main__:friendList []for i in range(0, 9):randomNumber random.randint(0, 100)friend Friend(f&qu…

【linux】network服務啟動網卡流程

目錄 1、介紹2、ifup流程【1】與NetworkManager兼容【2】ifup-eth設置ip【3】ifup-routes設置路由 1、介紹 network服務的核心由/etc/sysconfig/network-scripts/下一堆腳本配置來生效&#xff0c;其中啟動網卡就是通過ifup腳本來實現的&#xff0c;下面就講一下ifup如何恢復i…

如何防止自己的電腦被控制?開啟二次驗證保護教程

遠程操作什么最重要&#xff1f;安全&#xff0c;安全&#xff0c;和安全&#xff01;答案永遠是安全&#xff01;那么究竟如何能讓遠程連接安全性更上一層臺階吶&#xff1f;又是哪家遠控安全策略方面最給力吶&#xff1f;這可不是王婆賣瓜&#xff0c;自賣自夸&#xff0c;確…

微信小程序節點相關總結

微信小程序節點事件總結 bindtap、catchtap、bindclick的區別&#xff1f;bindclick 和 bindtap 的區別在于&#xff1a; e.target和e.currentTargete.typee.timeStamp觸摸事件屬性&#xff08;針對觸摸類事件&#xff09;坐標信息事件綁定數據冒泡與捕獲相關其他特殊屬性**常見…

XSD是什么,與XML關系

XSD&#xff08;XML Schema Definition&#xff09;是用于描述XML文檔結構和內容的一種規范。它定義了XML文檔中元素、屬性、數據類型、數據格式以及它們之間的關系和約束。XSD是W3C&#xff08;萬維網聯盟&#xff09;推薦的標準之一&#xff0c;它比早期的DTD&#xff08;Doc…