清理buffer/cache/swap的方法梳理

来源:https://www.cnblogs.com/hackerer/archive/2018/12/10/10094698.html
-Advertisement-
Play Games

一、緩存機制介紹 在Linux系統中,為了提高文件系統性能,內核利用一部分物理記憶體分配出緩衝區,用於緩存系統操作和數據文件,當內核收到讀寫的請求時,內核先去緩存區找是否有請求的數據,有就直接返回,如果沒有則通過驅動程式直接操作磁碟。緩存機制優點:減少系統調用次數,降低CPU上下文切換和磁碟訪問頻率。 ...


一、緩存機制介紹

在Linux系統中,為了提高文件系統性能,內核利用一部分物理記憶體分配出緩衝區,用於緩存系統操作和數據文件,當內核收到讀寫的請求時,內核先去緩存區找是否有請求的數據,有就直接返回,如果沒有則通過驅動程式直接操作磁碟。
緩存機制優點:減少系統調用次數,降低CPU上下文切換和磁碟訪問頻率。
CPU上下文切換:CPU給每個進程一定的服務時間,當時間片用完後,內核從正在運行的進程中收回處理器,同時把進程當前運行狀態保存下來,然後載入下一個任務,這個過程叫做上下文切換。實質上就是被終止運行進程與待運行進程的進程切換。

Swap用途:Swap意思是交換分區,通常我們說的虛擬記憶體,是從硬碟中劃分出的一個分區。當物理記憶體不夠用的時候,內核就會釋放緩存區(buffers/cache)里一些長時間不用的程式,然後將這些程式臨時放到Swap中,也就是說如果物理記憶體和緩存區記憶體不夠用的時候,才會用到Swap。
swap清理:swapoff -a && swapon -a
註意:這樣清理有個前提條件,空閑的記憶體必須比已經使用的swap空間大

二、查看緩存區及記憶體使用情況

free命令用於檢測物理記憶體和交換記憶體已使用量和可用量(預設單位為KB)
[root@backup ~]# free -m           //使用-m參數表示以兆位元組為單位顯示記憶體
             total       used       free     shared    buffers     cached
Mem:         64181      44372      19809          3         12        216
-/+ buffers/cache:      44143      20038
Swap:        32767          0      32767
  
第一部分Mem行解釋:
total:記憶體總數;
used:已經使用的記憶體數;
free:空閑的記憶體數;
shared:當前已經廢棄不用;
buffers Buffer:緩存記憶體數;
cached Page:緩存記憶體數。
關係:total = used + free
  
第二部分(-/+ buffers/cache)解釋:
(-buffers/cache) used記憶體數:第一部分Mem行中的 used – buffers – cached
(+buffers/cache) free記憶體數: 第一部分Mem行中的 free + buffers + cached
  
可見-buffers/cache反映的是被程式實實在在吃掉的記憶體,而+buffers/cache反映的是可以挪用的記憶體總數。
  
第三部分是指交換分區。
  
---------------------------------------------------------------------------------------------
以位元組為單位顯示記憶體
加上-b參數的free命令,以位元組為單位顯示記憶體的大小。
  
[root@backup ~]# free -b
             total       used       free     shared    buffers     cached
Mem:    67299549184 46525181952 20774367232    3272704   12820480  227033088
-/+ buffers/cache: 46285328384 21014220800
Swap:   34359734272          0 34359734272
-------------------------------------------------------------------------------------------
以千位元組為單位顯示記憶體
加上-k參數的free命令(預設單位,所以可以不用使用它),以(KB)千位元組為單位顯示記憶體大小。
[root@backup ~]# free -k
             total       used       free     shared    buffers     cached
Mem:      65722216   45435760   20286456       3196      12520     221712
-/+ buffers/cache:   45201528   20520688
Swap:     33554428          0   33554428
-------------------------------------------------------------------------------------------
以千兆位元組為單位顯示記憶體
使用-g為參數,將會以GB(千兆位元組)為單位顯示記憶體大小。
[root@backup ~]# free -g
             total       used       free     shared    buffers     cached
Mem:            62         43         19          0          0          0
-/+ buffers/cache:         43         19
Swap:           31          0         31
------------------------------------------------------------------------------------------
定期時間間隔更新記憶體狀態
-s選項加上一個整數,用來在定期時間間隔內更新free命令。舉個例子,下麵的命令將會在每5秒更新一個free命令。
[root@backup ~]# free -s 5
             total       used       free     shared    buffers     cached
Mem:      65722216   45436660   20285556       3196      12712     222096
-/+ buffers/cache:   45201852   20520364
Swap:     33554428          0   33554428
  
             total       used       free     shared    buffers     cached
Mem:      65722216   45436592   20285624       3196      12720     222096
-/+ buffers/cache:   45201776   20520440
Swap:     33554428          0   33554428

  

三、buffers和cached解釋

=========================================================
緩存(cached)是把讀取過的數據保存起來,重新讀取時若命中(找到需要的數據)就不要去讀硬碟了,若沒有命中就讀硬碟。其中的數據會根據讀取頻率進行組織,把最頻繁讀取的內容放在最容易找到的位置,把不再讀的內容不斷往後排,直至從中刪除。

緩衝(buffers)是根據磁碟的讀寫設計的,把分散的寫操作集中進行,減少磁碟碎片和硬碟的反覆尋道,從而提高系統性能。linux有一個守護進程定期清空緩衝內容(即寫入磁碟),也可以通過sync命令手動清空緩衝。舉個例子吧:我這裡有一個ext2的U盤,我往裡面cp一個3M的MP3,但U盤的燈沒有跳動,過了一會兒(或者手動輸入sync)U盤的燈就跳動起來了。卸載設備時會清空緩衝,所以有些時候卸載一個設備時要等上幾秒鐘。

修改/etc/sysctl.conf中的vm.swappiness右邊的數字可以在下次開機時調節swap使用策略。該數字範圍是0~100,數字越大越傾向於使用swap。預設為60,可以改一下試試。–兩者都是RAM中的數據。

兩者都是RAM中的數據,簡單來說,buffer是即將要被寫入磁碟的,而cache是被從磁碟中讀出來的。
buffer是由各種進程分配的,被用在如輸入隊列等方面。一個簡單的例子如某個進程要求有多個欄位讀入,在所有欄位被讀入完整之前,進程把先前讀入的欄位放在buffer中保存。
cache經常被用在磁碟的I/O請求上,如果有多個進程都要訪問某個文件,於是該文件便被做成cache以方便下次被訪問,這樣可提高系統性能。
========================================================

Cache:緩衝區,高速緩存,是位於CPU與主記憶體間的一種容量較小但速度很高的存儲器。由於CPU的速度遠高於主記憶體,CPU直接從記憶體中存取數據要等待一定時間周期,Cache中保存著CPU剛用過或迴圈使用的一部分數據,當CPU再次使用該部分數據時可從Cache中直接調用,這樣就減少了CPU的等待時間,提高了系統的效率。Cache又分為一級Cache(L1 Cache)和二級Cache(L2 Cache),L1 Cache集成在CPU內部,L2 Cache早期一般是焊在主板上,現在也都集成在CPU內部,常見的容量有256KB或512KB L2 Cache。它是根據程式的局部性原理而設計的,就是cpu執行的指令和訪問的數據往往在集中的某一塊,所以把這塊內容放入cache後,cpu就不用在訪問記憶體了,這就提高了訪問速度。當然若cache中沒有cpu所需要的內容,還是要訪問記憶體的。從記憶體讀取與磁碟讀取角度考慮,cache可以理解為操作系統為了更高的讀取效率,更多的使用記憶體來緩存可能被再次訪問的數據。

Cache並不是緩存文件的,而是緩存塊的(塊是I/O讀寫最小的單元);Cache一般會用在I/O請求上,如果多個進程要訪問某個文件,可以把此文件讀入Cache中,這樣下一個進程獲取CPU控制權並訪問此文件直接從Cache讀取,提高系統性能。

Buffer:緩衝區,一個用於存儲速度不同步的設備或優先順序不同的設備之間傳輸數據的區域。通過buffer可以減少進程間通信需要等待的時間,當存儲速度快的設備與存儲速度慢的設備進行通信時,存儲慢的數據先把數據存放到buffer,達到一定程度存儲快的設備再讀取buffer的數據,在此期間存儲快的設備CPU可以乾其他的事情。

Buffer:一般是用在寫入磁碟的,例如:某個進程要求多個欄位被讀入,當所有要求的欄位被讀入之前已經讀入的欄位會先放到buffer中。Buffer是根據磁碟的讀寫設計的,把分散的寫操作集中進行,減少磁碟碎片和硬碟的反覆尋道,從而提高系統性能。linux有一個守護進程定期清空緩衝內容(即寫入磁碟),也可以通過sync命令手動清空緩衝。

cache是高速緩存,用於CPU和記憶體之間的緩衝;
buffer是I/O緩存,用於記憶體和硬碟的緩衝;

cache最初用於cpu cache,主要原因是cpu 與memory,由於cpu快,memory跟不上,且有些值使用次數多,所以放入cache中,主要目的是,重覆使用,並且一級\二級物理cache速度快,
buffer主要用於disk與 memory,主要是保護硬碟或減少網路傳輸的次數(記憶體數據表現dataSet).當然也可以提高速度(不會立即寫入硬碟或直接從硬碟中讀出的數據馬上顯示),重覆使用,最初最主要的目的是保護disk,

Free中的buffer和cache:(它們都是占用記憶體):
buffer : 作為buffer cache的記憶體,是塊設備的讀寫緩衝區
cache: 作為page cache的記憶體, 文件系統的cache

如果 cache 的值很大,說明cache住的文件數很多。如果頻繁訪問到的文件都能被cache住,那麼磁碟的讀IO bi會非常小。
========================================================

下麵通過一些簡單通俗的例子來說明下Cache和Buffer緩存之間的區別:

1)Cache緩存

假設某地發生了自然災害(比如地震),居民缺衣少食,於是派救火車去給若幹個居民點送水。救火車到達第一個居民點,開閘放水,老百姓就拿著盆盆罐罐來接水。假如說救火車在一個居民點停留100分鐘放完了水,然後重新儲水花半個小時,再開往下一個居民點。這樣一個白天來來來回回的,也就是4-5個居民點。

但我們想想,救火車是何等存在,如果把水龍頭完全打開,其強大的水壓能輕易衝上10層樓以上, 10分鐘就可以把水全部放完。但因為居民是拿盆罐接水,100%打開水龍頭那就是給人洗澡了,所以只能打開一小部分(比如10%的流量)。但這樣就降低了放水的效率(只有原來的10%了),10分鐘變100分鐘。

那麼,我們是否能改進這個放水的過程,讓救火車以最高效率放完水、儘快趕往下一個居民點呢?
方法就是:在居民點建蓄水池。
救火車把水放到蓄水池裡,因為是以100%的效率放水,10分鐘結束然後走人。居民再從蓄水池裡一點一點的接水。

我們分析一下這個例子,就可以知道Cache的含義了。
救火車要給居民送水,居民要從救火車接水,就是說居民和救火車之間有交互,有聯繫。
但救火車是"高速設備",居民是"低速設備",低速的居民跟不上高速的救火車,所以救火車被迫降低了放水速度以適應居民。
為了避免這種情況,在救火車和居民之間多了一層"蓄水池(也就是Cache)",它一方面以100%的高效和救火車打交道,另一方面以10%的低效和居民打交道,這就解放了救火車,讓其以最高的效率運行,而不被低速的居民拖後腿,於是救火車只需要在一個居民點停留10分鐘就可以了。
所以說,蓄水池是"活雷鋒",把高效留給別人,把低效留給自己。把10分鐘留給救火車,把100分鐘留給自己。

從以上例子可以看出,所謂Cache,就是"為了彌補高速設備和低速設備之間的矛盾"而設立的一個中間層。因為在現實里經常出現高速設備要和低速設備打交道,結果被低速設備拖後腿的情況。Cache的存在是為瞭解決什麼問題?速度太慢了,要加快速度!

以PC為例。CPU速度很快,但CPU執行的指令是從記憶體取出的,計算的結果也要寫回記憶體,但記憶體的響應速度跟不上CPU。CPU跟記憶體說:你把某某地址的指令發給我。記憶體聽到了,但因為速度慢,遲遲不見指令返回,這段時間,CPU只能無所事事的等待了。這樣一來,再快的CPU也發揮不了效率。
怎麼辦呢?在CPU和記憶體之間加一塊"蓄水池",也就是Cache(片上緩存),這個Cache速度比記憶體快,從Cache取指令不需要等待。當CPU要讀記憶體的指令的時候先讀Cache再讀記憶體,但一開始Cache是空著的,只能從記憶體取,這時候的確是很慢,CPU需要等待。但從記憶體取回的不僅僅是CPU所需要的指令,還有其它的、當前不需要的指令,然後把這些指令存在Cache里備用。CPU再取指令的時候還是先讀Cache,看看裡面有沒有所需指令,如果碰巧有就直接從Cache取,不用等待即可返回(命中),這就解放了CPU,提高了效率。(當然不會是100%命中,因為Cache的容量比記憶體小)

2)Buffer緩存

比如說吐魯番的葡萄熟了,要用大卡車裝葡萄運出去賣果園的姑娘採摘葡萄,當然不是前手把葡萄摘下來,後手就放到卡車上,而是需要一個中間過程"籮筐":摘葡萄→放到籮筐里→把籮筐里的葡萄倒入卡車。也就是說,雖然最終目的是"把葡萄倒入卡車",但中間必須要經過"籮筐"的轉手,這裡的籮筐就是Buffer。是"暫時存放物品的空間"。
註意2個關鍵詞:暫時,空間
再換句話說,為了完成最終目標:把葡萄放入卡車的空間,需要暫時把葡萄放入籮筐的空間。

以BT為例,BT下載需要長時間的掛機,電腦就有可能24小時連軸轉,但BT下載的數據是碎片化的,體現在硬碟寫入上也是碎片化的,因為硬碟是機械定址器件,這種碎片化的寫入會造成硬碟長時間高負荷的機械運動,造成硬碟過早老化損壞,當年有大量的硬碟因為BT下載而損壞。於是新出的BT軟體在記憶體里開闢了Buffer,數據暫時寫入Buffer,攢到一定的大小(比如512M)再一次性寫入硬碟,這種"化零為整"的寫入方式大大降低了硬碟的負荷。這就是:為了完成最終目標:把數據寫入硬碟空間,需要暫時寫入Buffer的空間。

3)二者之間的區別總結

Cache和Buffer的相同點:都是2個層面之間的中間層,都是記憶體。
Cache和Buffer的不同點:Cache解決的是時間問題,Buffer解決的是空間問題。
為了提高速度,引入了Cache這個中間層。
為了給信息找到一個暫存空間,引入了Buffer這個中間層。
為瞭解決2個不同維度的問題(時間、空間),恰巧取了同一種解決方法:加入一個中間層,先把數據寫到中間層上,然後再寫入目標。
這個中間層就是記憶體“RAM”,既然是存儲器就有2個參數:寫入的速度有多塊(速度),能裝多少東西(容量)
Cache利用的是RAM提供的高讀寫速度,Buffer利用的是RAM提供的存儲容量(空間)。

a)Buffer(緩衝區)是系統兩端處理速度平衡(從長時間尺度上看)時使用的。它的引入是為了減小短期內突發I/O的影響,起到流量整形的作用。比如生產者——消費者問題,他們產生和消耗資源的速度大體接近,加一個buffer可以抵消掉資源剛產生/消耗時的突然變化。
b)Cache(緩存)則是系統兩端處理速度不匹配時的一種折衷策略。因為CPU和memory之間的速度差異越來越大,所以人們充分利用數據的局部性(locality)特征,通過使用存儲系統分級(memory hierarchy)的策略來減小這種差異帶來的影響。
c)假定以後存儲器訪問變得跟CPU做計算一樣快,cache就可以消失,但是buffer依然存在。比如從網路上下載東西,瞬時速率可能會有較大變化,但從長期來看卻是穩定的,這樣就能通過引入一個buffer使得OS接收數據的速率更穩定,進一步減少對磁碟的傷害。
========================================================

四、手動清理緩

釋放緩存區記憶體的方法
1)清理pagecache(頁面緩存)
[root@backup ~]# echo 1 > /proc/sys/vm/drop_caches     或者 # sysctl -w vm.drop_caches=1
 
2)清理dentries(目錄緩存)和inodes
[root@backup ~]# echo 2 > /proc/sys/vm/drop_caches     或者 # sysctl -w vm.drop_caches=2
 
3)清理pagecache、dentries和inodes
[root@backup ~]# echo 3 > /proc/sys/vm/drop_caches     或者 # sysctl -w vm.drop_caches=3
 
上面三種方式都是臨時釋放緩存的方法,要想永久釋放緩存,需要在/etc/sysctl.conf文件中配置:vm.drop_caches=1/2/3,然後sysctl -p生效即可!
 
另外,可以使用sync命令來清理文件系統緩存,還會清理僵屍(zombie)對象和它們占用的記憶體
[root@backup ~]# sync
 
 
溫馨提示:
上面操作在大多數情況下都不會對系統造成傷害,只會有助於釋放不用的記憶體。
但是如果在執行這些操作時正在寫數據,那麼實際上在數據到達磁碟之前就將它從文件緩存中清除掉了,這可能會造成很不好的影響。
 
那麼如果避免這種事情發生呢?
因此,這裡不得不提一下/proc/sys/vm/vfs_cache_pressure這個文件,告訴內核,當清理inoe/dentry緩存時應該用什麼樣的優先順序。
[root@backup ~]# cat /proc/sys/vm/vfs_cache_pressure
100
 
vfs_cache_pressure=100    這個是預設值,內核會嘗試重新聲明dentries和inodes,並採用一種相對於頁面緩存和交換緩存比較"合理"的比例。
 
減少vfs_cache_pressure的值,會導致內核傾向於保留dentry和inode緩存。
增加vfs_cache_pressure的值,(即超過100時),則會導致內核傾向於重新聲明dentries和inodes
  
總之,vfs_cache_pressure的值:
小於100的值不會導致緩存的大量減少
超過100的值則會告訴內核你希望以高優先順序來清理緩存。
  
其實無論vfs_cache_pressure的值採用什麼值,內核清理緩存的速度都是比較低的。
如果將此值設置為10000,系統將會將緩存減少到一個合理的水平。
======================================================
 
這裡順便說下自己遇到的一個記憶體問題:
IDC機房有一臺專門的備份伺服器,每天凌晨執行多個備份腳本。某天早上突然發現收到很多條zabbix監控報警信息:這台備份伺服器的記憶體使用了已超過80%!
於是,趕緊登陸這台備份伺服器,使用free命令查看記憶體使用情況:
[root@backup ~]# free -m
             total       used       free     shared    buffers     cached
Mem:         64181      48585      15596          3          2         18
-/+ buffers/cache:      48564      15617
Swap:        32767          0      3276
 
確實發現記憶體使用率已超過80%!但是使用"top"命令查看,發現此時並沒有什麼進程在占用記憶體,並且本機是備份伺服器,只有晚上執行備份腳本,
其他時間都沒有服務進程在跑!於是嘗試手動釋放記憶體:
[root@backup ~]# echo 1 > /proc/sys/vm/drop_caches
[root@backup ~]# echo 2 > /proc/sys/vm/drop_caches
[root@backup ~]# echo 3 > /proc/sys/vm/drop_caches
[root@backup ~]# sync
 
發現在執行了上面第三條命令後,記憶體才真正被釋放出來了,其他命令都沒有起到效果。

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一. MVC作用 一. SpringMVC 是一個輕量級的,基於請求響應的框架 一. 為什麼使用springMVC a) 性能較struts2好,struts2效率高(包含ActionContext) b) 簡單便捷,易學 c) 天生和spring無縫集成(主要銜接springIOC,AOP) d) ...
  • 網上普遍使用的化學方程式的格式普遍如下 例: KMnO4+FeSO4+H2SO4=Fe2(SO4)3+MnSO4+K2SO4+H2O 要把化學方程式格式化,單單一個正則表達式是非常反人類的,故可選用 C++ 實現化學方程式的格式化。 首先,寫一個 for 迴圈,傳入字元數組 input[] ,依次地 ...
  • 正式開始 首先我在這介紹兩個新的小知識,要在下麵用到。一個是函數 id() ,另一個是運算符 is。id() 函數就是返回對象的記憶體地址;is 是比較兩個變數的對象引用是否指向同一個對象,在這裡請不要和 == 混了,== 是比較兩個變數的值是否相等。 copy 這個詞有兩種叫法,一種是根據它的發音音 ...
  • 這裡主要介紹ANSI C的特性:當執行算術運算時,操作數的類型如果不同,就會發生轉換。數據類型一般朝著精度更高、長度更長的方向轉換,整型數如果轉換為signed不會丟失信息,就轉換為signed,否則轉換為unsigned。 一、算術轉換(K&R C) 首先: 任何類型為char或short的操作數 ...
  • using System; namespace ConsoleApp1 { interface IInterface1 { void ft(); } interface IInterface2 { void ft(); } class MyClass : IInterface1, IInterfa.... ...
  • 本周終於發佈了.NET Core 2.2,ASP.NET Core 2.2以及Entity Framework Core 2.2,雖然更大的新聞可能是.NET Core 3.0的特性公佈,但不妨先將現有的.NET Core版本升級到2.2,及時體驗一下新的功能。 .NET Core 2.2 分層編譯 ...
  • 1、錯誤案例: Index:1 Uncaught ReferenceError: 系統管理 is not defined at HTMLAnchorElement.onclick (Index:1) 2、錯誤寫法 3、正確寫法(加入轉義符號 ' \ ' ) ...
  • 在 Asp.Net Core 1.0 時代,由於設計上的問題, HttpClient 給開發者帶來了無盡的困擾,用 Asp.Net Core 開發團隊的話來說就是:我們註意到,HttpClient 被很多開發人員不正確的使用。得益於 .Net Core 不斷的版本快速升級;解決方案也一一浮出水面,本... ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...