java垃圾收集器與內(nèi)存分配策略詳解
1.經(jīng)典垃圾收集器
1.1 Serial收集器
這個(gè)收集器是一個(gè)單線程工作的收集器,但它的單線程的意義并不僅僅是說(shuō)明他只會(huì)使用一個(gè)處理器或一條收集線程去完成垃圾收集工作,更重要對(duì)的是強(qiáng)調(diào)在它進(jìn)行垃圾收集時(shí),必須暫停其他所有工作線程,直到它收集結(jié)束。
目前已經(jīng)老無(wú)可用,但有著優(yōu)于其他收集器的地方:簡(jiǎn)單而高效
1.2 ParNew收集器
ParNew收集器實(shí)質(zhì)上是Serial收集器的多線程并行版本。因?yàn)樗浅薙erial收集器之外,目前唯一可以與CMS收集器配合工作的收集器,所以在JDK7之前的遺留系統(tǒng)中被作為首選的新生代收集器
CMS收集器是HotSpot虛擬機(jī)中第一款真正意義上支持并發(fā)的垃圾收集器,首次實(shí)現(xiàn)了讓垃圾收集線程與用戶(hù)線程同時(shí)工作。但是當(dāng)選用CMS作為老年代收集器時(shí),新生代收集器只能選擇使用Serial收集器或者ParNew收集器
隨著垃圾收集器技術(shù)的不斷改進(jìn),G1收集器帶著CMS繼承者和代替者的光環(huán)登場(chǎng)。G1收集器是一個(gè)面向全堆的收集器,不需要其他新生代收集器的配合工作
1.3 Parallel Scavenge 收集器
Parallel Scavenge收集器也是一款新生代收集器,同樣是基于標(biāo)記-復(fù)制算法實(shí)現(xiàn)的收集器,也可以并行收集的多線程收集器。它的特點(diǎn)是它的關(guān)注點(diǎn)與其他收集器不同。CMS等收集器的關(guān)注點(diǎn)是盡可能地縮短垃圾收集時(shí)用戶(hù)線程的停頓時(shí)間,而Parallel Scavenge收集器的目標(biāo)則是達(dá)到一個(gè)可控制的吞吐量。
$$
吞吐量=\frac{運(yùn)行用戶(hù)代碼時(shí)間}{運(yùn)行用戶(hù)代碼時(shí)間+運(yùn)行垃圾收集時(shí)間}
$$
提供了兩個(gè)參數(shù)用于精確控制吞吐量:
-XX:MaxGCPauseMillis
參數(shù)控制最大垃圾搜集停頓時(shí)間,允許的值是一個(gè)大于0的毫秒數(shù)。收集器將盡力保證內(nèi)存回收花費(fèi)的時(shí)間不超過(guò)用戶(hù)的設(shè)定值。但是設(shè)定過(guò)分小的值并不能起到加快回收花費(fèi)的速度的作用。
-XX:GCTimeRatio
參數(shù)直接設(shè)置吞吐量大小,允許的值是一個(gè)大于0小于100的整數(shù)。也就是垃圾收集時(shí)間占總時(shí)間的比率。相當(dāng)于吞吐量的倒數(shù)。
Parallel Scavenge 收集器還有一個(gè)參數(shù):-XX:+UseAdaptiveSizePolicy
這是一個(gè)開(kāi)關(guān)參數(shù),當(dāng)這個(gè)參數(shù)被激活以后,就不需要人工指定新生代的大小,Eden與Survivor區(qū)的比例等等。虛擬機(jī)會(huì)根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況收集性能監(jiān)控信息,動(dòng)態(tài)調(diào)整這些參數(shù)。
1.4 Serial Old 收集器
Serial Old 是 Serial收集器的老年代版本,同樣是一個(gè)單線程收集器,使用標(biāo)記-整理算法??赡苡袃煞N用途:1. 在JDK5以及之前的版本中與Parallel Scavenge收集器搭配使用 2. 作為CMS收集器發(fā)生失敗時(shí)的后備預(yù)案。
1.5 Parallel Old 收集器
Parallel Old 是 Parallel Scavenge收集器的老年代版本,支持多線程并發(fā)收集,基于標(biāo)記-整理算法實(shí)現(xiàn),從JDK6版本開(kāi)始提供。在注重吞吐量或者處理器資源較為稀缺的場(chǎng)合,都可以?xún)?yōu)先考慮Parallel Scavenge加Parallel Old收集器這個(gè)組合。
1.6 CMS 收集器
CMS收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,基于標(biāo)記-清除算法實(shí)現(xiàn)。整個(gè)運(yùn)作過(guò)程分為4步:
步驟名稱(chēng) | 行為 |
---|---|
初始標(biāo)記(CMS initial mark) | 標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象,需要Stop The World |
并發(fā)標(biāo)記(CMS concurrent mark) | 從GC Roots的直接關(guān)聯(lián)對(duì)象開(kāi)始遍歷整個(gè)對(duì)象圖的過(guò)程,可以與垃圾收集線程一起并發(fā)運(yùn)行 |
重新標(biāo)記(CMS remark) | 修正并發(fā)標(biāo)記期間,因用戶(hù)程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,需要Stop the World |
并發(fā)清楚(CMS concurrent sweep) | 清理刪除掉標(biāo)記階段判斷的已經(jīng)死亡的對(duì)象,可以與用戶(hù)線程同時(shí)并發(fā)完成 |
CMS收集器存在三個(gè)缺點(diǎn):
1.CMS收集器對(duì)處理器資源非常敏感,默認(rèn)啟動(dòng)的回收線程數(shù)為(處理器核心數(shù)量+3)/ 4。在并發(fā)階段會(huì)因?yàn)檎加昧艘徊糠志€程而導(dǎo)致應(yīng)用程序變慢,降低總吞吐量。
為了緩解這種情況虛擬機(jī)提供了“增量式并發(fā)收集器”(Incremental Concurrent Mark Sweep/i-CMS)作用是在并發(fā)標(biāo)記、清理的時(shí)候讓收集器線程、用戶(hù)線程交替運(yùn)行,盡量減少垃圾收集器線程的獨(dú)占資源的時(shí)間,這樣整個(gè)垃圾收集的過(guò)程會(huì)更長(zhǎng),但是對(duì)用戶(hù)程序的影響就會(huì)顯得較少一些,直觀感受是速度變慢的時(shí)間更多了,但速度下降幅度就沒(méi)有那么明顯。效果一般從jdk7開(kāi)始被聲明為deprecated ,從JDK9發(fā)布后被完全廢棄
2.由于CMS收集器無(wú)法處理“浮動(dòng)垃圾”(Floating Garbage),有可能出現(xiàn)"Concurrent Mode Failure" 失敗進(jìn)而導(dǎo)致另一完全"Stop The World"的Full GC的產(chǎn)生。
可以適當(dāng)調(diào)高參數(shù)-XX:CMSInitiatingOccu-pancyFraction的值來(lái)提高CMS的觸發(fā)百分比,降低內(nèi)存回收頻率,獲得更好的性能。如果設(shè)置的太高將會(huì)很容易導(dǎo)致大量的并發(fā)失敗產(chǎn)生,性能反而降低
3.由于基于標(biāo)記-清除算法,可能在收集結(jié)束時(shí)會(huì)有大量的空間碎片產(chǎn)生
通過(guò)調(diào)節(jié):-XX:+UseCMSCompactAtFullCollection開(kāi)關(guān)參數(shù),默認(rèn)是開(kāi)啟的,從jdk9開(kāi)始廢棄
*** -XX:CMSFullGCsBeforeCompaction 默認(rèn)值是0,表示每次進(jìn)入Full GC時(shí)都進(jìn)行碎片整理***
1.7 Garbage First 收集器
Garbage First 收集器,簡(jiǎn)稱(chēng) G1收集器,開(kāi)創(chuàng)了收集器面向局部收集的設(shè)計(jì)思路和基于Region的內(nèi)存布局形式。是一款主要面向服務(wù)端應(yīng)用的垃圾收集器??梢悦嫦蚨褍?nèi)存的任何部分來(lái)組成回收集,衡量的標(biāo)準(zhǔn)不再是它屬于哪個(gè)分代,而是哪塊內(nèi)存中存放的垃圾數(shù)量最多,回收收益最大。G1開(kāi)創(chuàng)的基于Region的堆內(nèi)存布局是它能夠?qū)崿F(xiàn)這個(gè)目標(biāo)的關(guān)鍵,G1不再堅(jiān)持固定大小以及固定數(shù)量的分代區(qū)域劃分,而是把連續(xù)的java堆劃分為多個(gè)大小相等的獨(dú)立區(qū)域(Region),每一個(gè)Region都可以根據(jù)需要,扮演新生代的Eden空間、Survivor空間或者老年代空間。
Region中還有一類(lèi)特殊的Humongous區(qū)域,專(zhuān)門(mén)用來(lái)存儲(chǔ)大對(duì)象。G1認(rèn)為只要大小超過(guò)了Region容量一半的對(duì)象就可以判定為大對(duì)象。每個(gè)Region的大小可以通過(guò)參數(shù)-XX:G1HeapRegionSize設(shè)定,取值范圍為1MB~32MB。
G1收集器之所以可以建立可預(yù)測(cè)的停頓時(shí)間模型,是因?yàn)樗鼘egion作為單次回收的最小單元,即每次收集到的內(nèi)存空間都是Region大小的整數(shù)倍,這樣可以有計(jì)劃地避免在整個(gè)JAVA堆中進(jìn)行全區(qū)域的垃圾收集。更具體的思路是讓G1收集器區(qū)跟蹤各個(gè)Region里面的垃圾堆積的價(jià)值大小,價(jià)值即回收所獲得的空間大小以及回收所需要的時(shí)間的經(jīng)驗(yàn)值,然后在后臺(tái) 維護(hù)一個(gè)優(yōu)先級(jí)列表,每次根據(jù)用戶(hù)設(shè)定允許的收集停頓時(shí)間(-XX:MaxGCPauseMillis)優(yōu)先處理回收價(jià)值收益最大的那些Region。
G1的記憶集在存儲(chǔ)結(jié)構(gòu)的本質(zhì)上是一種哈希表,Key是別的Region的起始地址,Value是一個(gè)集合,里面存儲(chǔ)的元素是卡表的索引號(hào)。G1收集器通過(guò)原始快照(SATB)算法實(shí)現(xiàn)了保證其不能打破原本的對(duì)象圖結(jié)構(gòu)的目的。
G1收集器運(yùn)作過(guò)程大致分為四個(gè)步驟:
步驟 | 行為 |
---|---|
初始標(biāo)記(Initial Marking) | 標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象,并且修改TAMS指針的值。這個(gè)階段需要停頓線程,而且是借用進(jìn)行Minor GC的時(shí)候同步完成的 |
并發(fā)標(biāo)記(Concurrent Marking) | 從GC Root開(kāi)始對(duì)堆種對(duì)象進(jìn)行可達(dá)性分析,遞歸掃描整個(gè)堆里的對(duì)象圖,找出要回收的對(duì)象,可以與用戶(hù)程序并發(fā)執(zhí)行。對(duì)象圖掃描完成以后,還需要重新處理SATB記錄下的在并發(fā)時(shí)有引用變動(dòng)的對(duì)象 |
最終標(biāo)記(Final Marking) | 對(duì)用戶(hù)線程做另一個(gè)短暫的暫停,用于處理并發(fā)階段結(jié)束后仍遺留下來(lái)的最后那少量的SATB記錄 |
篩選回收(Live Data Counting and Evacuation) | 負(fù)責(zé)更新Region的統(tǒng)計(jì)數(shù)據(jù),對(duì)各個(gè)Region的回收價(jià)值和成本進(jìn)行排序,根據(jù)用戶(hù)所期望的停頓時(shí)間來(lái)制定回收計(jì)劃,可以自由選擇任意多個(gè)Region構(gòu)成回收集,然后把決定回收的那一部分Region的存活對(duì)象復(fù)制到空的Region中,再清理整個(gè)舊Region的全部空間,必須暫停用戶(hù)線程 |
2低延遲垃圾收集器
2.1 Shenandoah收集器
Shenandoah收集器是一款只有OpenJDK才會(huì)包含的。與G1收集器相比,它們兩者有著相似的堆內(nèi)存布局,在初始標(biāo)記、并發(fā)標(biāo)記等許多階段的處理思路上都高度一致。但是在管理內(nèi)存堆方面,與G1收集器至少有三個(gè)方面的明顯的不同之處:
1.支持并發(fā)的整理算法:G1的回收階段是可以多線程并行的,但不能與用戶(hù)線程并發(fā)。Shenandoah后面會(huì)講到。
2.Shenandoah收集器默認(rèn)不使用分代收集。
3.Shenandoah摒棄了在G1中耗費(fèi)大量?jī)?nèi)存和計(jì)算資源去維護(hù)的記憶集,改名為“連接矩陣”(Connection Matrix)的全局?jǐn)?shù)據(jù)結(jié)構(gòu)來(lái)記錄跨Region的引用關(guān)系。降低了處理跨代指針的記憶集維護(hù)消耗,也降低了偽共享問(wèn)題發(fā)生的概率
Shenandoah收集器大致工作流程可以分為9個(gè)階段:
步驟名稱(chēng) | 動(dòng)作 |
---|---|
初始標(biāo)記(Initial Marking) | 標(biāo)記與GC Roots直接關(guān)聯(lián)的對(duì)象,這個(gè)階段是Stop The World的,停頓時(shí)長(zhǎng)與堆大小無(wú)關(guān),與GC Roots的數(shù)量相關(guān)。 |
并發(fā)標(biāo)記(Concurrent Marking) | 遍歷對(duì)象圖,標(biāo)記出全部可達(dá)的對(duì)象,這個(gè)階段與用戶(hù)線程一起并發(fā)的,時(shí)間長(zhǎng)短取決于堆中存活對(duì)象的數(shù)量以及對(duì)象圖的結(jié)構(gòu)復(fù)雜程度。 |
最終標(biāo)記(Final Marking) | 處理剩余的SATB掃描,在這個(gè)階段統(tǒng)計(jì)出回收價(jià)值最高的Region,將這些Region構(gòu)成一組回收集,最終標(biāo)記階段也會(huì)有一小段短暫的停頓。 |
并發(fā)清理(Concurrent Cleanup) | 清理那些整個(gè)區(qū)域內(nèi)連一個(gè)存活對(duì)象都沒(méi)有找到的Region(這類(lèi)Region被稱(chēng)為Immediate Garbage Region)。 |
并發(fā)回收(Concurrent Evacuation) | 核心差異!Shenandoah要把回收集里面的存活對(duì)象先復(fù)制一份到其他未被使用的Region之中。Shenandoah會(huì)通過(guò)讀屏障和被成稱(chēng)為"Brooks Points"的轉(zhuǎn)發(fā)指針來(lái)解決在復(fù)制對(duì)象時(shí)遇到的困難。時(shí)間長(zhǎng)短取決于回收集的大小。 |
初始引用更新(Initial Update Reference) | 把堆中所有指向舊對(duì)象的引用修正到復(fù)制后的新地址,這個(gè)操作稱(chēng)為引用更新。在此階段,只是建立了一個(gè)線程集合點(diǎn),確保所有的并發(fā)回收階段中進(jìn)行的收集器線程都已完成分配給它們的對(duì)象移動(dòng)任務(wù)而已。時(shí)間會(huì)很短,有一個(gè)十分短暫的停頓。 |
并發(fā)引用更新(Comcurrent Update Reference) | 真正開(kāi)始進(jìn)行引用更新操作,與用戶(hù)線程一起并發(fā)的,時(shí)間長(zhǎng)短取決于內(nèi)存中涉及的引用數(shù)量的多少。只需要按照內(nèi)存物理地址的順序,線性搜索出引用類(lèi)型,把舊值改為新值即可。 |
最終引用更新(Final Update Reference) | 解決了堆中的引用更新后,還要修正存在于GC Roots中的引用。這個(gè)階段是最后一次停頓,時(shí)間與GC Roots的數(shù)量有關(guān)。 |
并發(fā)清理(Concurrent Cleanup) | 此時(shí)整個(gè)回收集中所有的Region已再無(wú)存活對(duì)象,都變成了Immediate Garbage Regions了,最后調(diào)用一次并發(fā)清理過(guò)程來(lái)回收這些Region的內(nèi)存空間,供以后新對(duì)象分配使用。 |
Brooks Points:Brooks是一個(gè)人的名字,它提出使用了轉(zhuǎn)發(fā)指針(Forwarding Pointer)的技術(shù)來(lái)實(shí)現(xiàn)對(duì)象移動(dòng)與用戶(hù)程序并發(fā)的一種解決方案。不需要用到內(nèi)存保護(hù)陷阱,而是在原有對(duì)象布局結(jié)構(gòu)的最前面統(tǒng)一增加一個(gè)新的引用字段,在正常不處于并發(fā)移動(dòng)的情況下,該引用指向?qū)ο笞约?。?shí)際上Shenandoah收集器是通過(guò)比較并交換(Compare And Swap, CAS)操作來(lái)保證并發(fā)時(shí)對(duì)象的訪問(wèn)正確性的。
JDK13中Shenandoah的內(nèi)存屏障模型改進(jìn)為基于引用訪問(wèn)屏障(Load Reference Barrier)的實(shí)現(xiàn),所謂“引用訪問(wèn)屏障”是指內(nèi)存屏障只攔截對(duì)象中數(shù)據(jù)類(lèi)型為引用類(lèi)型的讀寫(xiě)操作,而不去管原生數(shù)據(jù)類(lèi)型等其他非引用字段的讀寫(xiě)。這能省去大量對(duì)原生類(lèi)型、對(duì)象比較、對(duì)象加鎖等場(chǎng)景中設(shè)置內(nèi)存屏障所帶來(lái)的消耗。
2.2 ZGC收集器
ZGC收集器是一款基于Region內(nèi)存布局的,暫時(shí)不設(shè)分代的,使用了讀屏障、染色指針和內(nèi)存多重映射等技術(shù)來(lái)實(shí)現(xiàn)可并發(fā)的標(biāo)記-整理算法的,以低延遲為首要目標(biāo)的一款垃圾收集器。
ZGC的Region具有動(dòng)態(tài)性-動(dòng)態(tài)創(chuàng)建和銷(xiāo)毀,以及動(dòng)態(tài)的區(qū)域容量大小。
染色指針(Colored Pointer):一種直接將少量額外的信息存儲(chǔ)在指針上的技術(shù)。盡管在linux下64位指針的高18位不能用來(lái)尋址,但是剩余的46位所能支持的64TB內(nèi)存仍然能夠充分滿(mǎn)足需要。鑒于此,將其高4位提取出來(lái)存儲(chǔ)四個(gè)標(biāo)記信息。通過(guò)這些標(biāo)志位,虛擬機(jī)可以直接從指針中看到其引用對(duì)象的三色標(biāo)記狀態(tài)、是否進(jìn)入了重分配集、是否只能通過(guò)finalize( )方法才能被訪問(wèn)到。也使得ZGC能夠管理的內(nèi)存不可以超過(guò)4TB。使用染色指針的三大優(yōu)勢(shì):
1.可以使得一旦某個(gè)Region的存活對(duì)象被移走之后,這個(gè)Region立即就能被釋放和重用掉,不必等待整個(gè)堆中所有指向該Region的引用都被修正后才能清理。
2.可以大幅度減少在垃圾收集過(guò)程中的內(nèi)存屏障的使用數(shù)量。到目前為止,ZGC都未使用寫(xiě)屏障,只使用了讀屏障。
3.可以作為一種可擴(kuò)展的存儲(chǔ)結(jié)構(gòu)用來(lái)記錄更多與對(duì)象標(biāo)記、重定位過(guò)程相關(guān)的數(shù)據(jù),以便日后進(jìn)一步提高性能。
Linux/x86-64平臺(tái)上的ZGC使用了多重映射將多個(gè)不同的虛擬內(nèi)存地址映射到同一個(gè)物理內(nèi)存地址上,意味著ZGC在虛擬內(nèi)存中看到的地址空間要比實(shí)際的堆內(nèi)存容量來(lái)得更大。把染色指針中的標(biāo)志位看作是地址的分段符,只要將這些不同的地址段都映射到同一個(gè)物理內(nèi)存空間,經(jīng)過(guò)多重映射轉(zhuǎn)換后,就可以使用染色指針正常進(jìn)行尋址了。
ZGC的運(yùn)作過(guò)程(省略部分與之前介紹的G1和Shenandoah相同的小階段部分):
步驟 | 動(dòng)作 |
---|---|
并發(fā)標(biāo)記(Concurrent Mark) | 遍歷對(duì)象圖做可達(dá)性分析的階段,前后也要經(jīng)過(guò)初始標(biāo)記、最終標(biāo)記的短暫停頓。ZGC的標(biāo)記是在指針上而不是在對(duì)象上進(jìn)行的,標(biāo)記階段會(huì)更新染色指針中的Marked 0、Marked 1 標(biāo)志位。 |
并發(fā)預(yù)備重分配(Concurrent Prepare for Relocate) | 根據(jù)特定的查詢(xún)條件統(tǒng)計(jì)得出本次收集過(guò)程要清理那些Region,將這些Region組成重分配集。與G1收集器的回收集還是有區(qū)別的,ZGC的重分配集只是決定了里面的存活對(duì)象會(huì)被重新分配復(fù)制到其他的Region中,里面的Region會(huì)被釋放,而并不能說(shuō)回收行為就只是針對(duì)這個(gè)集合里面的Region進(jìn)行,因?yàn)闃?biāo)記過(guò)程是針對(duì)全堆的。 |
并發(fā)重分配(Concurrent Reolcate) | 核心階段!把重分配集中的存活對(duì)象復(fù)制到新的Region上,并未重分配集中的每個(gè)Region維護(hù)一個(gè)轉(zhuǎn)發(fā)表,記錄從舊對(duì)象到新對(duì)象的轉(zhuǎn)向關(guān)系。 |
并發(fā)重映射(Concurrent Remap) | 修正整個(gè)堆中指向重分配集中舊對(duì)象的所有引用。 |
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java泛型T,E,K,V,N,?與Object區(qū)別和含義
Java?泛型(generics)是?JDK?5?中引入的一個(gè)新特性,?泛型提供了編譯時(shí)類(lèi)型安全檢測(cè)機(jī)制,該機(jī)制允許程序員在編譯時(shí)檢測(cè)到非法的類(lèi)型。本文將詳細(xì)講講Java泛型T、E、K、V、N、?和Object區(qū)別和含義,需要發(fā)可以參考一下2022-03-03Java 創(chuàng)建線程的3種方法及各自的優(yōu)點(diǎn)
這篇文章主要介紹了Java 創(chuàng)建線程的3種方法及各自的優(yōu)點(diǎn),文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07關(guān)于Mybatis的mapper接口函數(shù)重載問(wèn)題
這篇文章主要介紹了關(guān)于Mybatis的mapper接口函數(shù)重載問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02簡(jiǎn)單了解SPRINGIOC的底層原理演變過(guò)程
這篇文章主要介紹了簡(jiǎn)單了解SPRINGIOC的底層原理演變過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10關(guān)于MyBatis 查詢(xún)數(shù)據(jù)時(shí)屬性中多對(duì)一的問(wèn)題(多條數(shù)據(jù)對(duì)應(yīng)一條數(shù)據(jù))
這篇文章主要介紹了MyBatis 查詢(xún)數(shù)據(jù)時(shí)屬性中多對(duì)一的問(wèn)題(多條數(shù)據(jù)對(duì)應(yīng)一條數(shù)據(jù)),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Java詳細(xì)分析連接數(shù)據(jù)庫(kù)的流程
Java數(shù)據(jù)庫(kù)連接,JDBC是Java語(yǔ)言中用來(lái)規(guī)范客戶(hù)端程序如何來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的應(yīng)用程序接口,提供了諸如查詢(xún)和更新數(shù)據(jù)庫(kù)中數(shù)據(jù)的方法。JDBC也是Sun Microsystems的商標(biāo)。我們通常說(shuō)的JDBC是面向關(guān)系型數(shù)據(jù)庫(kù)的2022-05-05