主頁 > 後端開發 > 解讀JVM虛擬機

解讀JVM虛擬機

2020-10-15 20:37:09 後端開發

概要點:

  • java虛擬機概述和基本概念
  • 堆、堆疊、方法區
  • 了解虛擬機引數
  • 垃圾回收概念和演算法、及物件的分代轉換
  • 垃圾收集器

java虛擬機的原理:

  • 所謂虛擬機,就是一臺虛擬的機器,它是一款軟體,用來執行一系列虛擬計算機指令,大體上虛擬機可以分為系統虛擬機和程式虛擬機,大名鼎鼎的Visual Box、VMare就屬于系統虛擬機,他們完全是對物理計算機的仿真,提供了一個可運行完整作業系統的軟體平臺,
  • 程式虛擬機典型代表就是Java虛擬機,它專門為執行單個計算機程式而設計,在java虛擬機中執行的指令我們成為java位元組碼指令,無論是系統虛擬機還是程式虛擬機,在上面運行的軟體都被限制于虛擬機提供的資源中,Java發展至今,出現過很多虛擬機,最初Sun使用的一款叫Classic的Java虛擬機,到現在參考最廣泛的是HotSpot虛擬機,除了Sun意外,還有BEA的JRockit,目前JRockit和HotSpot都被Oracle收入旗下,大有整合的趨勢,

java虛擬機的基本結構

 

結構概念說明:

  • 類加載子系統:負責從檔案系統或者網路中加載Class資訊,加載的資訊 存放在一塊稱之為方法區的記憶體空間,
  • 方法區:就是存放類資訊、常量資訊、常量池資訊、包括字串字面量和數字常量等,
  • java堆:在java虛擬機啟動的時候建立java堆,它是java程式最主要的記憶體作業區域,幾乎所有的物件實體都存放到java堆中,堆空間是所有執行緒共享的,
  • 直接記憶體:Java的NIO庫允許java程式使用直接記憶體,從而提高性能,通常直接記憶體速度會優于java堆,讀寫頻繁的場合可能會考慮使用,
  • 每個虛擬機執行緒都有一個私有的堆疊,一個執行緒的java堆疊在執行緒創建的時候被創建,java堆疊中保存著區域變數、方法引數、同時java的方法呼叫、回傳值等,
  • 本地方法堆疊和java堆疊非常類似,最大不同為本地方法堆疊用于本地方法呼叫,java虛擬機允許java直接呼叫本地方法(通常使用C撰寫),
  • 垃圾收集系統是java的核心,也是必不可少的,java有一套自己進行垃圾清理的機制,開發人員無需手工清理,我們稍后詳細說明,
  • PC(Program Counter)暫存器也是每個執行緒私有的空間,java虛擬機會為每個執行緒創建PC暫存器,在任意時刻,一個java執行緒總是在執行一個方法,這個方法被稱為當前方法,如果當前方法不是本地方法,PC暫存器就會執行當前正在被執行的指令,如果是本地方法,則PC暫存器值為undefined,暫存器存放如當前執行環境指標、程式計數器、操作堆疊指標、計算的變數指標等資訊,
  • 虛擬機最核心的組件就是執行引擎了,它負責執行虛擬機的位元組碼,一般戶先進行編譯成機器碼后執行

堆、堆疊、方法區概念和聯系:

  • 堆解決的是資料存盤的問題,即資料怎么放、放在哪兒, 堆疊解決程式的運行問題,即程式如何執行,或者說如何處理資料,
  • 方法區則是輔助堆疊的快永久區(Perm),解決堆疊資訊的產生,是先決條件,
  • 我們創建一個新的物件,User:那么User類的一些資訊(類資訊、靜態資訊都存在于方法區中) 而User類被實體化出來之后,被存盤到java堆中,一塊記憶體空間 當我們去使用的時候,都是使用User物件的參考,形如User user = new User(); 這里的user就是存放在java堆疊中的,即User真實物件的一個參考,

java堆疊:

  • java堆疊是一塊執行緒私有的記憶體空間,一個堆疊,一般由三部分組成:區域變數表、運算元堆疊和幀資料區,
  • 區域變數表:用于報錯函式的引數及區域變數, 運算元堆疊:主要保存計算程序的中間結果,同時作為計算程序中變數臨時的存盤空間,
  • 幀資料區:除了區域變數表和運算元堆疊以外,堆疊還需要一些資料來支持常量池的決議,這里幀資料區保存著訪問常量池的指標,方便程式訪問常量池,
  • 另外,當函式回傳或者出現例外時,虛擬機必須有一個例外處理表,方便發送例外的時候找到例外的代碼,因此例外處理表也是幀資料區的一部分,

 

 

 

java方法區:

  • java方法區和堆一樣,方法區是一塊所有執行緒共享的記憶體區域,它保存系統的類資訊,比如類的欄位、方法、常量池等,
  • 方法區的大小決定了系統可以保存多少個類,如果系統定義太多的類,導致方法區溢位,虛擬機同樣會拋出記憶體溢位錯誤,方法區可以理解為永久區(Perm)

 

虛擬機引數:

  • 在虛擬機運行的程序中,如果可以跟蹤系統的運行狀態,那么對于問題的故障排查會有一定的幫助,
  • 為此,虛擬機提供了一些跟蹤系統狀態的引數,使用給定的引數執行java虛擬機,就可以在系統運行時列印相關日志,用于分析實際問題,我們進行虛擬機引數配置,其實主要就是圍繞著堆、堆疊、方法區進行配置,

堆分配引數(一):

  • -XX:+PrintGC 使用這個引數,虛擬機啟動后,只要遇到GC就會列印日志,
  • -XX:+UseSerialGC 配置串行回收器
  • -XX:+PrintGCDetails 可以查看詳細資訊,包括各個區的情況
  • -Xms:設定java程式啟動時初始堆大小
  • -Xmx:設定java程式能獲得的最大堆大小
  • -Xmx20m -Xms5m -XX:+PrintCommandLineFlags : 可以將隱式或者顯示傳給虛擬機的引數輸出
  • 總結:在實際作業中,我們可以直接將初始的堆大小與最大堆大小設定相等,這樣的好處是可以減少程式運行時的垃圾回收次數,從而提高性能,

 

堆分配引數(二):

  • 新生代的配置 -Xmn:可以設定新生代的大小,設定一個比較大的新生代會減少老年代的大小,這個引數對系統性能以及GC行為有很大的影響,新生代大小一般會設定整個堆空間的1/3到1/4左右,
  • -XX:SurvivorRatio:用來設定新生代中eden空間和from/to空間的比例,含義:-XX:SurvivorRatio=eden/from=eden/to
  • 總結:不同的堆分布情況,對系統執行會產生一定的影響,在實際作業中,應該根據系統的特點做出合理的配置,基本策略:盡可能將物件預留在新生代,減少老年代的GC次數, 除了可以設定新生代的絕對大小(-Xmn),還可以使用(-XX:NewRatio)設定新生代和老年代的比例:-XX:NewRatio=老年代/新生代

 

堆溢位處理:

  • 在java程式的運行程序中,如果堆空間不足,則會拋出記憶體溢位的錯誤(Out Of Menory)OOM,一旦這類問題發生在生產環境,可能引起嚴重的業務中斷,
  • java虛擬機提供了-XX:+HeapDumpOnOutOfMemoryError,使用該引數可以在記憶體溢位時匯出整個堆資訊,與之配合使用的還有引數, -XX:HeapDumpPath,可以設定匯出堆的存放路徑,

 

堆疊配置:

  • Java虛擬機提供了引數-Xss來指定執行緒的最大堆疊空間,整個引數也直接決定了函式可呼叫的最大深度,

 

方法區:

  • 和java堆一樣,方法區是一塊所有執行緒共享的記憶體區域,它用于保存系統的類資訊,方法區(永久區)可以保存多少資訊可以對其進行配置,
  • 在默認情況下,-XX:MaxPermSize為64MB,如果系統運行時生產大量的類,就需要設定一個相對合適的方法區,以免出現永久區記憶體溢位的問題, -XX:PermSize=64M -XX:MaxPermSize=64M

 

直接記憶體配置:

  • 直接記憶體也是java程式中非常重要的組成部分,特別是廣泛用在NIO中,直接記憶體跳過了java堆,使java程式可以直接訪問原生堆空間,因此在一定程度上加快了記憶體空間的訪問速度,但是說直接記憶體一定就可以提高記憶體訪問速度也不見得,具體情況具體分析,
  • 相關配置引數:-XX:MaxDirectMemorySize,如果不設定默認值為最大堆空間,即-Xmx,直接記憶體使用達到上限時,就會觸發垃圾回收,如果不能有效的釋放空間,也會引起系統的OOM.

 

垃圾回收概念和其演算法:

  • 談到垃圾回收(Garbage Collection,簡稱GC),需要先澄清什么是垃圾,類比日常生活中的垃圾,我們會把他們丟入垃圾桶,然后倒掉,
  • GC中的垃圾,特指存于記憶體中、不會再被使用的物件,而回收就是相當于把垃圾“倒掉”, 垃圾回收有很多種演算法:如參考計數法、標記壓縮法、復制演算法、分代、磁區的思想,

 

垃圾收集演算法(一):

  • 參考計數法:這是個比較古老而經典的垃圾收集演算法,其核心就是在物件被其他所參考時計數器加1,而當參考失效時則減1,但是這種方式有非常嚴重的問題:無法處理回圈參考的情況、還有就是每次進行加減操作比較浪費系統性能, 標記清除法:就是分為標記和清除倆個階段進行處理記憶體中的物件,當然這種方式也有非常大的弊端,就是空間碎片問題,垃圾回收后的空間不是連續的,不連續的記憶體空間的作業效率要低于連續的記憶體空間,
  • 復制演算法:其核心思想就是將記憶體空間分為兩塊,,每次只使用其中一塊,在垃圾回收時,將正在使用的記憶體中的存留物件復制到未被使用的記憶體塊中去,之后去清除之前正在使用的記憶體塊中所有的物件,反復去交換倆個記憶體的角色,完成垃圾收集,(java中新生代的from和to空間就是使用這個演算法)
  • 標記壓縮法:標記壓縮法在標記清除法基礎之上做了優化,把存活的物件壓縮到記憶體一端,而后進行垃圾清理,(java中老年代使用的就是標記壓縮法) 考慮一個問題:為什么新生代和老年代使用不同的演算法?

 

垃圾收集演算法(二):

  • 分代演算法:就是根據物件的特點把記憶體分成N塊,而后根據每個記憶體的特點使用不同的演算法, 對于新生代和老年代來說,新生代回收頻率很高,但是每次回收耗時都很短,而老年代回收頻率較低,但是耗時會相對較長,所以應該盡量減少老年代的GC.
  • 磁區演算法:其主要就是將整個記憶體分為N多個小的獨立空間,每個小空間都可以獨立使用,這樣細粒度的控制一次回收都少個小空間和那些個小空間,而不是對整個空間進行GC,從而提升性能,并減少GC的停頓時間,

 

垃圾回收時的停頓現象:

  • 垃圾回收器的任務是識別和回收垃圾物件進行記憶體清理,為了讓垃圾回收器可以高效的執行,大部分情況下,會要求系統進入一個停頓的狀態,
  • 停頓的目的是終止所有應用執行緒,只有這樣系統才不會有新的垃圾產生,同事停頓保證了系統狀態在某一個瞬間的一致性,也有益于更好低標記垃圾物件,因此在垃圾回收時,都會產生應用程式的停頓,

 

物件如何進入老年代:

  • 一般而言物件首次創建會被放置在新生代的eden區,如果沒有GC介入,則物件不會離開eden區,那么eden區的物件如何進入老年代呢?
  • 一般來講,只要物件的年齡達到一定的大小,就會自動離開年輕代進入老年代,物件年齡是由物件經歷數次GC決定的,在新生代每次GC之后如果物件沒有被回收則年齡加1.虛擬機提供了一個引數來控制新生代物件的最大年齡,當超過這個年齡范圍就會晉升老年代, -XX:MaxTenuringThreshold,默認情況下為15,
  • 總結:根據設定MaxTenuringThreshold引數,可以指定新生代物件經過多少次回收后進入老年代, 另外,大物件(新生代eden區無法裝入時,也會直接進入老年代),JVM里有個引數可以設定物件的大小超過在指定的大小之后,直接晉升老年代, -XX:PretenureSizeThreshold

  • 總結:使用PretenureSizeThreshold可以進行指定進入老年代的物件大小,但是要注意TLAB區域優先分配空間,

 

物件創建流程圖:

 

 

 

垃圾收集器:

  • 在java虛擬機中,垃圾回收器不僅僅只有一種,什么情況下該使用哪種,對性能又有什么樣的影響,這都是我們需要了解的,
  • 串行垃圾回收器
  • 并行垃圾回收器
  • CMS回收器
  • G1回收器

 

串行回收器:

  • 串行回收器是指使用單執行緒進行垃圾回收的回收器,每次回收時,串行回收器只有一個作業執行緒,對于并行能力較弱的計算機來說,串行回收器的專注性和獨占性往往有更好的性能表現,
  • 串行回收器可以在新生代和老年代使用,根據作用于不同的堆空間,分為新生代串行回收器和老年代串行回收器, 使用-XX:+UseSerialGC 引數可以設定使用新生代串行回收器和老年代串行回收器

 

并行回收器(ParNew回收器):

  • 并行回收器在串行回收器基礎上做了改進,他可以使用多個執行緒同時進行垃圾回收,對于計算能力強的計算機而言,可以有效的縮短垃圾回收所需的實際時間,
  • ParNew回收器是一個作業在新生代的垃圾收集器,他只是簡單的將串行回收器多執行緒化,他的回收策略和演算法和串行回收器一樣,
  • 使用 -XX:+UseParNewGC 新生代ParNew回收器,老年代則使用串行回收器 ParNew回收器作業時的執行緒數量可以使用
  • -XX:ParallelGCThreads引數指定,一般最好和計算機的CPU相當,避免過多的執行緒影響性能,

 

并行回收器(ParallelGC回收器):

  • 新生代ParallelGC回收器,使用了復制演算法的收集器,也是多執行緒獨占形式的收集器,但ParallelGC回收器有個非常重要的特點,就是它非常關注系統的吞吐量,
  • 提供了倆個非常關鍵的引數控制系統的吞吐量
  • -XX:MaxGCPauseMillis:設定最大垃圾收集停頓時間,可用把虛擬機在GC停頓的時間控制在MaxGCPauseMillis范圍內,如果希望減少GC停頓時間可以將MaxGCPauseMillis設定的很小,但是會導致GC頻繁,從而增加了GC的總時間,降低了吞吐量,所以需要根據實際情況設定該值,
  • -XX:GCTimeRatio:設定吞吐量大小,它是一個0到100之間的整數,默認情況下他的取值是99,那么系統將花費不超過1/(1+n)的時間用于垃圾回收,也就是1/(1+99) = 1%的時間,
  • 另外還可以指定 -XX:+UseAdaptiveSizePolicy打開自適應模式,在這種模式下,新生代的大小、eden、from/to的比例,以及晉升老年代的物件年齡引數會被自動調整,以達到在堆大小、吞吐量和停頓時間之間的平衡點,

 

并行回收器(ParallelOldGC回收器):

  • 老年代ParallelOldGC回收器也是一種多執行緒的回收器,和新生代的ParallelGC回收器一樣,也是一種關注吞吐量的回收器,他使用了標記壓縮演算法進行實作,
  • -XX:+UseParallelOldGC 進行設定
  • -XX:+ParallelGCThreads 也可以設定垃圾收集時的執行緒數量,

 

CMS回收器:

  • CMS全稱為:Concurrent Mark Sweep 意為并發標記清除,他使用的是標記清除法,主要關注系統停頓時間,
  • 使用 -XX:+UseConcMarkSweepGC 進行設定,
  • 使用 -XX:ConcGCThreads 設定并發執行緒數量,
  • CMS并不是獨占的回收器,也就說CMS回收的程序中,應用程式仍然在不停的作業,又會有新的垃圾不斷的產生,所以在使用CMS的程序中應該確保應用程式的記憶體足夠可用,CMS不會等到應用程式飽和的時候才去回收垃圾,而是在某一閥值的時候開始回收,回收閥值可用指定的引數進行配置,-XX:CMSInitiatingOccupancyFraction來指定,默認為68,也就是說當老年代的空間使用率達到68%的時候,會執行CMS回收,如果記憶體使用率增長的很快,在CMS執行的程序中,已經出現了記憶體不足的情況,此時CMS回收就會失敗,虛擬機將啟動老年代串行回收器進行垃圾回收,這會導致應用程式中斷,知道垃圾回收完成后才會正常作業,這個程序GC的停頓時間可能較長,所以 - XX:CMSInitiatingOccupancyFraction的設定要根據實際的情況,
  • 標記清除法有個缺點就是存在記憶體碎片的問題,那么CMS有個引數設定-XX:+UseCMSCompactAtFullCollecion可以使CMS回收完成之后進行一次碎片整理,-XX:CMSFullGCsBeforeCompaction引數可以設定進行多少次CMS回收之后,對記憶體進行一次壓縮,

 

G1回收器:

  • G1回收器(Garbage-First)實在jdk1.7中正式使用的垃圾回收器,從長期目標來看是為了取代CMS回收器,G1回收器擁有獨特的垃圾回收策略,G1屬于分代垃圾回收器,區分新生代和老年代,依然有eden和from/to區,它并不要求整個eden區或者新生代、老年代的空間都連續,它使用了磁區演算法,
  • 并行性:G1回收期間可多執行緒同時作業,
  • 并發性:G1擁有與應用程式交替執行能力,部分作業可與應用程式同時執行,在整個GC期間不會完全阻塞應用程式,
  • 分代GC:G1依然是一個分代的收集器,但是它是兼顧新生代和老年代一起作業,之前的垃圾收集器他們或者在新生代作業,或者在老年代作業,因此這是一個很大的不同, 空間整理:G1在回收程序中,不會像CMS那樣在若干次GC后需要進行碎片整理,G1采用了有效復制物件的方式,減少空間碎片,
  • 可預見性:由于磁區的原因,G1可以只選取部磁區域進行回收,縮小了回收的范圍,提升了性能,
  • 使用 -XX:+UseG1GC 應用G1收集器
  • 使用 -XX:MaxGCPauseMillis 指定最大停頓時間
  • 使用 -XX:ParallelGCThreads 設定并行回收的執行緒數量

 

Tomcat性能影響實驗:

  • 配置環境說明: Tomcat7
  • 一個JSP網站 測驗網站吞吐量(1個指標、停頓時間,記憶體的使用情況,包括回收的效率....)
  • 工具: Apache JMeter 下載地址:http://jmeter.apache.org/download_jmeter.cgi
  • 實驗原理: 通過JMeter對Tomcat增加壓力,不同的虛擬機引數應該會有不同的表現
  • 目的: 觀察不同配置引數對吞吐量的影響

 

測驗串行回收器:

  • -XX:+PrintGCDetails -Xmx32M -Xms32M
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:+UseSerialGC -XX:PermSize=32M
  • 測驗結果顯示吞吐量為:1152 115

 

擴大堆記憶體以提升系統性能:

  • -XX:+PrintGCDetails -Xmx512M -Xms32M
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:+UseSerialGC
  • -XX:PermSize=32M -Xloggc:d:/gc.log
  • 測驗結果顯示吞吐量為:1557 155

 

調整初始堆大小:

  • -XX:+PrintGCDetails -Xmx512M -Xms64M
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:+UseSerialGC
  • -XX:PermSize=32M -Xloggc:d:/gc.log
  • 測驗結果顯示吞吐量為:2100 209

 

測驗ParNew回收器的表現:

  • -XX:+PrintGCDetails -Xmx512M -Xms64M
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:+UseParNewGC -XX:PermSize=32M -Xloggc:d:/gc.log
  • 測驗結果顯示吞吐量為:2200 220

 

使用ParallelOldGC回收器:

  • -XX:+PrintGCDetails -Xmx512M -Xms64M
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:+UseParallelGC -XX:+UseParallelOldGC
  • -XX:ParallelGCThreads=8 -XX:PermSize=32M -Xloggc:d:/gc.log
  • 測驗結果顯示吞吐量為:3336 330

 

測驗CMS回收器的性能:

  • -XX:+PrintGCDetails -Xmx512M -Xms64M
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:+UseConcMarkSweepGC -XX:ConcGCThreads=8
  • -XX:PermSize=32M -Xloggc:d:/gc.log
  • 測驗結果顯示吞吐量為:2100  209

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

標籤:Java

上一篇:intelij idea快捷鍵

下一篇:Git 基本應用

標籤雲
其他(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