① 簡述入侵檢測常用的四種方法
入侵檢測系統所採用的技術可分為特徵檢測與異常檢測兩種。
1、特徵檢測
特徵檢測(Signature-based detection) 又稱Misuse detection ,這一檢測假設入侵者活動可以用一種模式來表示,系統的目標是檢測主體活動是否符合這些模式。
它可以將已有的入侵方法檢查出來,但對新的入侵方法無能為力。其難點在於如何設計模式既能夠表達「入侵」現象又不會將正常的活動包含進來。
2、異常檢測
異常檢測(Anomaly detection) 的假設是入侵者活動異常於正常主體的活動。根據這一理念建立主體正常活動的「活動簡檔」,將當前主體的活動狀況與「活動簡檔」相比較,當違反其統計規律時,認為該活動可能是「入侵」行為。
異常檢測的難題在於如何建立「活動簡檔」以及如何設計統計演算法,從而不把正常的操作作為「入侵」或忽略真正的「入侵」行為。
(1)somd5源碼擴展閱讀
入侵分類:
1、基於主機
一般主要使用操作系統的審計、跟蹤日誌作為數據源,某些也會主動與主機系統進行交互以獲得不存在於系統日誌中的信息以檢測入侵。
這種類型的檢測系統不需要額外的硬體.對網路流量不敏感,效率高,能准確定位入侵並及時進行反應,但是佔用主機資源,依賴於主機的可靠性,所能檢測的攻擊類型受限。不能檢測網路攻擊。
2、基於網路
通過被動地監聽網路上傳輸的原始流量,對獲取的網路數據進行處理,從中提取有用的信息,再通過與已知攻擊特徵相匹配或與正常網路行為原型相比較來識別攻擊事件。
此類檢測系統不依賴操作系統作為檢測資源,可應用於不同的操作系統平台;配置簡單,不需要任何特殊的審計和登錄機制;可檢測協議攻擊、特定環境的攻擊等多種攻擊。
但它只能監視經過本網段的活動,無法得到主機系統的實時狀態,精確度較差。大部分入侵檢測工具都是基於網路的入侵檢測系統。
3、分布式
這種入侵檢測系統一般為分布式結構,由多個部件組成,在關鍵主機上採用主機入侵檢測,在網路關鍵節點上採用網路入侵檢測,同時分析來自主機系統的審計日誌和來自網路的數據流,判斷被保護系統是否受到攻擊。
② linux下安裝Apache+ASP環境的原因
為什麼要在Linux下安裝ASP環境?且看這幾個原因夠不夠:
A.
作為Linux下的開發環境
B.
當IIS中的ASP僅用於後台,同時使用人數較少.前台頁面主要以HTML靜態頁面展示,ASP用來做的事情較少,本身對系統的負擔很輕
綜合以上,當ASP顯得有點雞肋時,相應的應用完全可以移植到Linux下,以充分發揮Linux下系統平台優勢和資源優勢。
因為ASP本為Windows下IIS的原生產物,移植到Linux下確實有些怪異,所以實現方案也比較少,目前能找到的基本以Perl轉義為主。
在Linux下安裝ASP環境必須的環境支持為:
Apache+Apache的perl模塊+perl的Apache::ASP包,請看安裝步驟:
1.安裝Apache::ASP(也可在第3步之後安裝)
perl
-MCPAN
-e
shell
install
CPAN
install
MLDBM
install
MLDBM::Sync
install
Apache::ASP
如果通過perl安裝失敗,可以去下載這幾個源代碼包:
Digest-MD5-2.20.tar.gz
MLDBM-2.01.tar.gz
MLDBM-Sync-0.30.tar.gz
Apache-ASP-2.37.tar.gz
按順序展開源代碼,各自執行以下操作安裝:
perl
Makefile.PL
make
make
test
make
install
2.安裝Apache,
在Linux環境下模擬ASP環境目前僅能查到Apache+ASP的方案
#下載
tar
zxf
httpd-2.2.15.tar.gz
cd
httpd-2.2.15
./configure
--prefix=/usr/local/apache
make
make
install
cd
..
3.安裝apache的mod_perl模塊
#下載apache的perl模塊
wget
tar
zxf
mod_perl-2.0-current.tar.gz
cd
mod_perl-2.0.4/
perl
Makefile.PLUSE_APXS=1
WITH_APXS=/usr/local/apache/bin/apxs
EVERYTHING=1
make
make
install
cd
..
4.httpd.conf配置:
因為ASP環境不是我們在Linux下要用的主用環境,主用環境是Nginx,所以將Apache監聽埠修改為80埠之外的埠,我修改為81
Listen
81
網站根目錄也需修改成Nginx網站根目錄,例如我的Nginx網站根目錄為:/var/webhosts/htdocs/www,那麼需要修改如下2個位置:
DocumentRoot
"/var/webhosts/htdocs/www"
在httpd.conf文件末尾追加如下內容:
LoadMole
perl_mole
moles/mod_perl.so
PerlMole
Apache::ASP
SetHandler
perl-script
PerlHandler
Apache::ASP
PerlSetVar
Global
.
PerlSetVar
StateDir
/tmp/asp
ok,ASP環境安裝完成,啟動Apache試試:)
/usr/local/apache/bin/apachectl
start
在網站根目錄下創建test.asp,內容如下:
For
loop
incrementing
font
size:
<%
for(1..7)
{
%>
Size
=
<%=$_%>
<%
}
%>
③ hash文件怎麼打開
hash如何打開文件?
(hash文件在哪裡打開)
很多朋友下載了一個文件打不開,或者打開後根本不是這樣。有些朋友甚至下載了一個官方系統,但安裝了一堆病毒,這通常是由於下載的文件貨物錯誤造成的。由於網路問題,CDN由於緩存甚至釣魚網站等原因,默認情況下很難判斷下載的文件是否會錯誤。要解決這個問題,對文件進行Hash哈希校驗是一種非常有效的做法,但是Windows這個功能選項似乎沒有默認。怎麼辦?今天就享幾招!
命令行
其實說Windows默認沒有Hash文件的功能不準確,Windows其實系統是有的Hash文件功能,但不直接提供給用戶,可以通過命令行執行Hash命令。
首先,我們需要查詢文件的具體路徑,這很簡單,可以通過點擊文件呼出右鍵菜單來查看屬性。
接著,運行PowerShell,輸入以下命令。
Get-FileHash -Algorithm | Format-List
其中,填寫文件的位置,填寫你想操作的Hash類型。Windows默認支持SHA1、SHA256、SHA384、SHA512、MACTripleDES、MD5、RIPEMD不支持160演算法CRC-32、CRC-64。
例如,有一份文件叫做1.jpgC盤的根目錄存在,想用MD驗證演算法時,應輸入以下命令。
Get-FileHash C:\\1.jpg -Algorithm md5| Format-List
之後,PowerShell中就會給出Hash值了。
7-Zip
命令行雖然有用,但畢竟麻煩,有沒有更簡單的方法?實際上可以著用7-Zip壓縮軟體。
7-Zip:https://www.7-zip.org/
7-Zip我相信很多人都聽說過這個名字。它是世界上最流行的開源壓縮軟體之一,具有巨大的影響力。許多壓縮軟體,特別是國內壓縮軟體,使用了7個-Zip的源代碼。但鮮為人知的是,其實7-Zip除了幫助您壓縮和解壓文件外,它還提供了非常方便和快速的文件Hash文件功能。
打開7-Zip點擊工具進入選項的主界面,可以看到多個選項卡。切換到「7-Zip」,勾選「添加7-Zip到右鍵菜單,檢查以下CRC SHA選項,然後用右鍵單擊文件,可以看到7-Zip提供的Hash功能了。
7-Zip支持CRC-32、CRC-64、SHA256、SHA1以及BLAKE2sp等Hash演算法很好地彌補了Windows自帶Hash演算法不足。可惜的是7-Zip沒有提供非常常見的MD5,如果需要MD5的Hash,還得另尋他法。
OpenHashTab
7-Zip雖然不錯,但其本職始終是壓縮軟體。若需要更專業的解決方案,OpenHashTab也許是更完美的選擇。
OpenHashTab:https://github.com/namazso/OpenHashTab
OpenHashTab是一款開源的、專注於提供Hash小軟體驗證功能。它體積小,支持中文,沒有使用門檻。
OpenHashTab使用簡單,下載後可直接安裝。之後,只要打開文件屬性,就可以看到哈希信息的標簽,上面列出了各種哈希值。
OpenHashTab功能專業全面。在支持演算法方面,OpenHashTab支持以下Hash演算法。
CRC32, CRC64 (xz)
xxHash (XXH32, XXH64)
xxHash3 (64 and 128 bit variants)
MD4, MD5
RipeMD160
Blake2sp
SHA-1
SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512)
SHA-3 (SHA3-224, SHA3-256, SHA3-384, SHA3-512)
BLAKE3 (256 bit, 512 bit)
KangarooTwelve (264 bit, 256 bit, 512 bit)
ParallelHash128 (264 bit) and ParallelHash256 (528 bit)
Streebog (GOST R 34.11-12) (256 bit, 512 bit)
另外,OpenHashTab還支持文件夾,也可以選擇多個文件一起計算Hash,雙擊計算Hash復制值很方便。
一般來說,如果你經常有計算文件Hash的需求,OpenHashTab這將是一個很好的選擇。
一般來說,如果你經常有計算文件Hash的需求,OpenHashTab這將是一個很好的選擇。
總結擔心下載的文件出錯,使用Hash比較確實是一種有效的方法。目前Windows默認的Hash功能不方便,希望以上方法能對大家有所幫助!
④ AndroidKillerV131正式版AndroidKillerV131正式版功能簡介
大家好,關於Android Killer V1.3.1 正式版,Android Killer V1.3.1 正式版功能簡介這個很多人還不知道,現在讓我們一起來看看吧!
Android Killer最新版是一款功能強大的安卓APK反匯編工具,軟體集APK反編譯、APK打包、APK簽名,編碼互轉,ADB通信等特色功能於一身,支持logcat日誌輸出,能夠大大簡化安卓應用和游戲修改過程中各類繁瑣工作。
【功能特點】
1、可視化、全自動的反編譯、編譯、簽名;支持批量編譯APK。
2、以樹形目錄管理反編譯出的Apk源碼文件,瀏覽、打開、編輯、都可以統一在軟體中實現,不同項目間可以自由切換,方便快捷。
3、自動識別圖像資源,並提供該類資源的快捷替換功能,方便修改這類圖片資源。
4、內置代碼編輯器,支持包含,但不限於.samli、.xml、.html等各類格式文件的語法高亮顯示,根據 smali文件格式的自動匹配相應語法;同時支持使用系統編輯器來編輯代碼文件。
5、內置基於文件內容的單行或多行代碼關鍵字搜索、可顯示無窮多個搜索結果以標簽的形式分門別類;可指定搜索范圍,整個項目或在指定的文件或文件夾中搜索、大小寫,編碼類型;從此無需再藉助其他工具,即可輕松的完成搜索任務。
6、內嵌Unicode、UTF8、ANSI編碼互轉工具,方便硬編碼文字的檢索以及相關漢化類修改。
7、內置Log等調試工具,方便應用進程、logcat輸出查看等進階操作,監測修改apk的運行狀況,以助於分析和查找錯誤
8、內置ADB功能,包括使用ADB向設備,或模擬器安裝、卸載、運行修改後的apk,進行測試,並可管理所連接設備的存儲文件,包括系統以及用戶文件
9、所有操作步驟、結果都會顯示在日誌窗口,方便查看。
10、默認支持記事本、計算器等小工具,開放設置介面可根據需要自定義外部工具,滿足個性化需求。
【更新內容】
增加中英文版本切換,相關提示信息沒有英化,有其他語言需求者在 "AK\cfgs\lang\" 路徑下手動處理
增加自動識別java的bin目錄
修復搜索批量替換後編譯出錯的BUG
增加 APK 簽名工具
增加 APK 簽名多項自定義添加
增加 APK 編譯完後是否自動簽名選項
增加 Apktool 管理器,用於 apktool 版本切換(支持反編譯時參數定義)、框架安裝和卸載等功能
增加 APK 安裝管理器工具,移除上一版本的簡單APK推送安裝功能
增加 MD5 查看器工具
增加方法聲明中只查看本地方法的功能,用於快速過濾查看 smali 對 so 中的方法調用
增加文本搜索工具
增加圖片資源預覽子目錄功能
增加識別最新版的娜迦殼
增加搜索後批量替換功能
增加批量刪除工程項
增加日誌信息多選復制功能
增加 Androidkiller lua 腳本功能
更新 dex2jar 為最新版本
調整 APK 簽名方式,去除從設置中選擇簽名,只保留簽名的添加及編輯功能,改為從編譯按鈕的下拉菜單中選擇
調整一些內部邏輯
調整搜索清空、管理項置頂
調整 apktool 默認為 ShakeApktool 版本
修復搜索中文字元時高亮位置錯誤
修復工程信息相關BUG
⑤ 軍哥求助 pureftpd FTP 連接數 無法更改
FTP不安全,萬不得已情況下,才可使用。vsftp安全性相對較好可採用sftp代替FTPLinux另外常用的FTP:proftpvsftppureftp下面以VSFTP為例:安裝方式一:源碼包安裝useradd -s /bin/false -d /var/ftp ftpvirtualcd ......makemake installcp vsftpd.conf /etc/usr/local/sbin/vsftpd & #啟動安裝方式二:rpm安裝,推薦rpm -ivh vsftpd-2.0.1-5.i386.rpm或者 yum install vsftpd/etc/init.d/vsftpd start兩種方式安裝完成後,配置方法都一樣,下面開始講配置。首先講主配置文件常見配置vi /etc/vsftpd/vsftpd.confanonymous_enable=NO #禁止匿名登錄local_enable=NO #禁止本地用戶登錄 write_enable=YES #對本地用戶的寫許可權local_umask=022 #本地用戶文件生成掩碼dirmessage_enable=YES #顯示隱藏文件xferlog_enable=YES #啟用上傳和下載日誌connect_from_port_20=YES #伺服器將啟用FTP數據埠的連接請求xferlog_std_format=YES #伺服器將使用標準的ftpd xferlog日誌格式pam_service_name=vsftpd #設置PAM認證服務的配置文件名稱userlist_enable=YES #設置文件中指定的用戶是否可以訪問vsftpd伺服器listen=YES #FTP伺服器將處於獨立啟動模式 tcp_wrappers=YES #使用tcp_wrappers作為主機訪問控制方式 chroot_local_user=YES #將FTP本地用戶禁錮在宿主目錄中 chroot_list_enable=YES #將用戶禁錮在宿主目錄中listen_address=192.168.0.2 #偵聽地址pasv_enable=YES #是否允使用被動模式,默認是允許的。pasv_min_port=10000 #指定使用被動模式時打開埠的最小值pasv_max_port=10004 #指定使用被動模式時打開埠的最大值。max_clients=100 #設置FTP伺服器所允許的最大客戶端連接數,值為0時表示不限制 max_per_ip=5 #同一IP地址允許的最大客戶端連接數,值為0時表示不限制,即線程 local_max_rate=500000 #設置本地用戶的最大傳輸速率,單位為bytes/sec,值為0時表示不限制 anon_max_rate=200000 #設置匿名用戶的最大傳輸速率,單位為bytes/sec,值為0表示不限制 use_localtime=YES #在vsftp之中的時間默認值是顯式GMT時間,因此我們會發現上面的時間與我們時寄存取的時間差八小時。改了這一項就好了。listen_port=10021 改埠one_process_model=NO yes可增加性能,增加負載,便降低安全,建議NOnopriv_user=nobody 默認以nobody運行vsftp對外服務,建議使用stand alone方式啟動,性能好。僅內部人員,建議用super daemon啟動,修改如下:listen=NO……略vsftp默認使用GMT時間,建議修改如下:use_localtime=YES/etc/vsftpd.ftpusers #保存不允許進行FTP登錄的本地用戶帳號,提高系統的安全性/etc/vsftpd.user_list #禁止vsftpd.user_list中的用戶userlist_enable=YESuserlist_deny=YES #僅允許vsftpd.user_list中的用戶userlist_enable=YESuserlist_deny=NO 日誌:vsftpd_log_file=/var/log/vsftpd.log下面開始講vsftp四種「用戶認證」的方式一、匿名用戶 ftp anonymous/var/ftp 默認主目錄在/etc/vsftpd/vsftpd.conf中:anonymous_enable=YESanon_upload_enable=YESanon_other_write_enable=YES #可刪除chmod -R 777 /var/ftp/pub/修改/var/ftp/pub的SELinux許可權執行以下命令,修改/var/ftp/pub這目錄的類型:chcon -R -t ftpd_anon_rw_t /var/ftp/pub/anon_root=/var/www/html/ftp #改匿名用戶的宿主目錄二、本地用戶默認支持,使用各自的宿主目錄。不安全local_root=/opt #新增這一項,改成其他路徑三、虛擬用戶 PAM文件方式 推薦建立虛擬用戶口令庫文件# cat logins.txt mikepwabcdjohnpw1234生成vsftpd的認證文件db_load -T -t hash -f logins /etc/vsftpd/vsftpd_login.dbchmod 600 /etc/vsftpd/vsftpd_login.db 新創建虛擬用戶所需的PAM配置文件cat /etc/pam.d/vsftpd.vuauth required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_loginaccount required /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login 新創建虛擬用戶的系統用戶所要訪問的目錄並設置相應許可權# useradd -s /bin/false -d /home/ftpsite ftpvirtual# chmod 700 /home/ftpsite#設置vsftpd.conf配置文件,支持虛擬用戶guest_enable=YESguest_username=ftpvirtualpam_service_name=vsftpd.vu user_config_dir=/etc/vsftpd/vsftpd_user_conf #添加用戶配置文件目錄設置/etc/vsftpd/vsftpd_user_conf/mike (同名),這里沒有的設置默認按vsftpd.conf的設置執行anon_world_readable_only=NO #可以瀏覽FTP目錄和下載文件anon_upload_enable=YES #用戶可以上傳文件,等同於 write_enable=yes 允許上傳anon_mkdir_write_enable=YES #具有建立和刪除目錄的權利 anon_other_write_enable=YES #具有文件改名和刪除文件的許可權 local_root=/data/userspace #設置虛擬用戶登錄後的主目錄anon_max_rate=1024000 #以Bytes/s為單位,這里限8Mbit,范圍大概在80%到120%之間四、虛擬用戶 mysql認證方式 推薦1. mysql安裝見mysql筆記2.1 openssl-0.9.8e 源程序預編譯時在日誌中可能出現md5.h "Present But Cannot Be Compiled的錯誤,卸載下面某些包可能解決問題。cyrus-sals-sql cyrus-sasl-ntlm cyrus-sasl-gssapi cyrus-sasl-devel openldap-devel然後移除系統可能自帶的:mv /usr/bin/openssl /usr/bin/openssl.OFFmv /usr/include/openssl /usr/include/openssl.OFFln -s /usr/local/ssl/bin/openssl /usr/bin/opensslln -s /usr/local/ssl/include/openssl /usr/include/openssl配置庫文件搜索路徑#echo "/usr/local/ssl/lib" >> /etc/ld.so.conf#ldconfig -v2.2 或者安裝openssl-0.9.8e的rpm包3. pam_mysql-0.7RC1.tar.gz#./configure --with-mysql=/usr/local/mysql --with-openssl=/usr/local/ssl如果mysql是rpm安裝的,則不帶--with-mysql參數,如果openssl是rpm安裝的,參數為--with-opensslmake;make install注意pam_mysql.so路徑,可能在/usr/lib/security/pam_mysql.so或/lib/security/pam_mysql.sovi /etc/pam.d/vsftp.mysql #新建,僅兩行auth required /lib/security/pam_mysql.so user=vsftpd passwd=123456 host=localhost db=vsftp table=users usercolumn=name passwdcolumn=passwd crypt=2account required /lib/security/pam_mysql.so user=vsftpd passwd=123456 host=localhost db=vsftp table=users usercolumn=name passwdcolumn=passwd crypt=24.0 准備資料庫、表和數據mysql> create database vsftp;mysql> grant select on vsftp.* to vsftpd@localhost identified by '123456';mysql> grant select on vsftp.* to [email protected] identified by '123456';mysql> use vsftp;mysql> create table users (-> id int AUTO_INCREMENT NOT NULL,-> name char(20) binary NOT NULL,-> passwd char(48) binary NOT NULL,-> primary key(id)-> );mysql> insert into users(name,passwd) values('hlc',password('hlc'));mysql> insert into users(name,passwd) values('holly',password('holly'));5.0 修改主配置文件vi /etc/vsftpd/vsftpd.confguest_enable=YESguest_username=vsftplisten=YESpam_service_name=vsftpd.mysql以上完成了vsftp的配置,下面是補充:dirmessage_enable=YES #設置歡迎語 在每個目錄下建立.message,寫入歡迎語即可。db_load支持包(前面三個即可):db4db4-develdb4-utilsdb4-javadb4-tclLinux建議關閉selinux或征對FTP不做任何安全setsebool -P -ftpd_disable_trans onsetsebool -P -allow_ftpd_full_access onservie vsftpd restart或者需要重啟伺服器底下列出FTP訪問中所出現數字代碼的含意。110 重新啟動標記應答。 120 服務在多久時間內ready。 125 數據鏈路埠開啟,准備傳送。 150 文件狀態正常,開啟數據埠。 200 命令執行成功。 202 命令執行失敗。 211 系統狀態或是系統求助響應。 212 目錄的狀態。 213 文件的狀態。 214 求助的訊息。 215 名稱系統類型。 220 新的聯機服務ready。 221 服務的控制埠關閉,可以注銷。 225 數據鏈接開啟,但無傳輸動作。 226 關閉數據埠,請求的文件操作成功。 227 進入passive mode。 230 用戶登錄。 250 請求的文件操作完成。 257 顯示目前的路徑名稱。 331 用戶名稱正確,需要密碼。 332 登入時需要帳戶信息。 350 請求的操作需要進一部的命令。 421 無法提供服務,關閉控制連結。 425 無法開啟數據鏈路。 426 關閉聯機,終止傳輸。 450 請求的操作未執行。 451 命令終止:有本地的錯誤。 452 未執行命令:磁碟空間不足。 500 格式錯誤,無法識別命令。 501 參數語法錯誤。 502 命令執行失敗。 503 命令順序錯誤。 504 命令所接的參數不正確。 530 未登入。 532 儲存文件需要賬戶登入。 550 未執行請求的操作。 551 請求的命令終止,類型未知。 552 請求的文件終止,儲存位溢出。 553 未執行請求的的命令,名稱不正確。
⑥ 存儲性能優化 MMKV源碼解析
好久沒有更新常用的第三方庫了。讓我們來聊聊MMKV這個常用的第三方庫。MMKV這個庫是做什麼的呢?他本質上的定位和sp有點相似,經常用於持久化小數據的鍵值對。其速度可以說是當前所有同類型中速度最快,性能最優的庫。
它的最早的誕生,主要是因為在微信iOS端有一個重大的bug,一個特殊的文本可以導致微信的iOS端閃退,而且還出現了不止一次。為了統計這種閃退的字元出現頻率以及過濾,但是由於出現的次數,發現原來的鍵值對存儲組件NSUserDefaults根本達不到要求,會導致cell的滑動卡頓。
因此iOS端就開始創造一個高新性能的鍵值對存儲組件。於此同時,Android端SharedPreferences也有如下幾個缺點:
因此Android也開始復用iOS的MMKV,而後Android有了多進程的寫入數據的需求,Android組又在這個基礎上進行改進。
這里是官方的性能的比較圖:
能看到mmkv比起我們開發常用的組件要快上數百倍。
那麼本文將會從源碼角度圍繞MMKV的性能為什麼會如此高,以及SharePrefences為什麼可能出現ANR的原因。
請注意下文是以MMKV 1.1.1版本源碼為例子分析。如果遇到什麼問題歡迎來到本文 https://www.jianshu.com/p/c12290a9a3f7 互相討論。
老規矩,先來看看MMKV怎麼使用。mmkv其實和SharePrefences一樣,有增刪查改四種操作。
MMKV作為一個鍵值對存儲組件,也對了存儲對象的序列化方式進行了優化。常用的方式比如有json,Twitter的Serial。而MMKV使用的是Google開源的序列化方案:Protocol Buffers。
Protocol Buffers這個方案比起json來說就高級不少:
使用方式可以閱讀下面這篇文章: https://www.jianshu.com/p/e8712962f0e9
下面進行比較幾個對象序列化之間的要素比較
而MMKV就是看重了Protocol Buffers的時間開銷小,選擇Protocol Buffers進行對象緩存的核心。
使用前請初始化:
當然mmkv除了能夠寫入這些基本類型,只要SharePrefences支持的,它也一定能夠支持。
同上,每一個key讀取的數據類型就是decodexxx對應的類型名字。使用起來十分簡單。
能夠刪除單個key對應的value,也能刪除多個key分別對應的value。containsKey判斷mmkv的磁碟緩存中是否存在對應的key。
mmkv和SharePrefences一樣,還能根據模塊和業務劃分對應的緩存文件:
這里創建了一個id為a的實例在磁碟中,進行數據的緩存。
當需要多進程緩存的時候:
MMKV可以使用Ashmem的匿名內存進行更加快速的大對象傳輸:
進程1:
最重要的一點,mmkv把SharePrefences的緩存遷移到mmkv中,之後的使用就和SharePrefences一致。
這里就是把SharedPreferences的myData數據遷移到mmkv中。當然如果我們需要保持SharePreferences的用法不變需要自己進行自定義一個SharePreferences。
mmkv的用法極其簡單,接下來我們關注他的原理。
首先來看看MMKV的初始化。
能看到實際上initialize分為如下幾個步驟:
能看到其實就是做這個判斷。由於此時設置的是libc++的打包方式。此時BuildConfig.FLAVOR就是StaticCpp,就不會載入c++_shared。當然,如果我們已經使用了c++_shared庫,則沒有必要打包進去,使用defaultPublishConfig "SharedCppRelease"會嘗試的查找動態鏈接庫_shared。這樣就能少2M的大小。
請注意一個前提的知識,jni的初始化,在調用了 System.loadLibrary之後,會通過dlopen把so載入到內存後,調用dlsym,調用jni中的JNI_OnLoad方法。
實際上這裡面做的事情十分簡單:
能從這些native方法中看到了所有MMKV的存儲方法,設置支持共享內存ashemem的存儲,支持直接獲取native malloc申請的內存
接下來就是MMKV正式的初始化方法了。
這個方法實際上調用的是pthread_once方法。它一般是在多線程環境中,根據內核的調度策略,選擇一個線程初始化一次的方法。
其實這裡面的演算法很簡單:
defaultMMKV此時調用的是getDefaultMMKV這個native方法,默認是單進程模式。從這里的設計都能猜到getDefaultMMKV會從native層實例化一個MMKV對象,並且讓實例化好的Java層MMKV對象持有。之後Java層的方法和native層的方法一一映射就能實現一個直接操作native對象的Java對象。
我們再來看看MMKV的mmkvWithID。
感覺上和defaultMMKV有點相似,也是調用native層方法進行初始化,並且讓java層MMKV對象持有native層。那麼我們可否認為這兩個實例化本質上在底層調用同一個方法,只是多了一個id設置呢?
可以看看MMKV.h文件:
這里就能看到上面的推測是正確的,只要是實例化,最後都是調用mmkvWithID進行實例化。默認的mmkv的id就是mmkv.default。Android端則會設置一個默認的page大小,假設4kb為例子。
所有的mmkvID以及對應的MMKV實例都會保存在之前實例化的g_instanceDic散列表中。其中mmkv每一個id對應一個文件的路徑,其中路徑是這么處理的:
如果發現對應路徑下的mmkv在散列表中已經緩存了,則直接返回。否則就會把相對路徑保存下來,傳遞給MMKV進行實例化,並保存在g_instanceDic散列表中。
我們來看看MMKV構造函數中幾個關鍵的欄位是怎麼初始化。
mmkvID就是經過md5後對應緩存文件對應的路徑。
能看到這里是根據當前的mode初始化id,如果不是ashmem匿名共享內存模式進行創建,則會和上面的處理類似。id就是經過md5後對應緩存文件對應的路徑。
注意這里mode設置的是MMKV_ASHMEM,也就是ashmem匿名共享內存模式則是如下創建方法:
實際上就是在驅動目錄下的一個內存文件地址。
接下來,在構造函數中使用了共享的文件鎖進行保護後,調用loadFromFile進一步的初始化MMKV內部的數據。
我們大致的了解MMKV中每一個欄位的負責的職責,但是具體如何進行工作下文都會解析。
在這裡面我們遇到了看起來十分核心的類MemoryFile,它的名字有點像 Ashmem匿名共享內存 一文中描述過Java層的映射的匿名內存文件。
我們先來看看MemoryFile的初始化。
MemeoryFile分為兩個模式進行初始化:
這里的處理很簡單:
能看到此時將會調用mmap系統調用,通過設置標志位可讀寫,MAP_SHARED的模式進行打開。這樣就file就在在內核中映射了一段4kb內存,以後訪問文件可以不經過內核,直接訪問file映射的這一段內存。
關於mmap系統調用的源碼解析可以看這一篇 Binder驅動的初始化 映射原理 。
能看到在這個過程中實際上還是通過ftruncate進行擴容,接著調用zeroFillFile,先通過lseek把指針移動當前容量的最後,並把剩餘的部分都填充空數據'\0'。最後映射指向的地址是有效的,會先解開後重新進行映射。
為什麼要做最後這個步驟呢?如果閱讀過我解析的mmap的源碼一文,實際上就能明白,file使用MAP_SHARED的模式本質上是給file結構體綁定一段vma映射好的內存。ftruncate只是給file結構體進行了擴容,但是還沒有對對應綁定虛擬內存進行擴容,因此需要解開一次映射後,重新mmap一次。
MMKV在如果使用Ashmem模式打開:
接下來loadFromFile 這個方法可以說是MMKV的核心方法,所有的讀寫,還是擴容都需要這個方法,從映射的文件內存,緩存到MMKV的內存中。
進入到這個方法後進行如下的處理:
在這里,遇到了一個比較有歧義的欄位m_version ,從名字看起來有點像MMKV的版本號。其實它指代的是MMKV當前的狀態,由一個枚舉對象代表:
注意m_vector是一個長度16的char數組。其實很簡單,就是把文件保存的m_vector獲取16位拷貝到m_metaInfo的m_vector中。因為aes的加密必須以16的倍數才能正常運作。
初始化分為這6點,我們從最後三點開始聊聊MMKV的初始化的核心邏輯。我們還需要開始關注MMKV中內存存儲的結構。
能看到首先從m_file獲取映射的指針地址,往後讀取4位數據。這4位數據就是actualSize 真實數據。但是如果是m_metaInfo的m_version 大於等於3,則獲取m_metaInfo中保存的actualSize。
其校驗的手段,是通過比較m_metaInfo保存的crcDigest和從m_file中讀取的crcDigest進行比較,如果一致說明數據無誤,則返回true,設置loadFromFile為true。
其實這裡面只處理m_metaInfo的m_version的狀態大於等於3的狀態。我們回憶一下,在readActualSize方法中,把讀取當前存儲的數據長度,分為兩個邏輯進行讀取。如果大於等於3,則從m_metaInfo中獲取。
crc校驗失敗,說明我們寫入的時候發生異常。需要強制進行recover恢復數據。
首先要清除crc校驗校驗了什麼東西:
MMKV做了如下處理,只處理狀態等級在MMKVVersionActualSize情況。這個情況,在m_metaInfo記錄上一次MMKV中的信息。因此可以通過m_metaInfo進行校驗已經存儲的數據長度,進而更新真實的已經記錄數據的長度。
最後讀取上一次MMKV還沒有更新的備份數據長度和crc校驗欄位,通過writeActualSize記錄在映射的內存中。
如果最後彌補的校驗還是crc校驗錯誤,最後會回調onMMKVCRCCheckFail這個方法。這個方法會反射Java層實現的異常處理策略
如果是OnErrorRecover,則設置loadFromFile和needFullWriteback都為true,盡可能的恢復數據。當然如果OnErrorDiscard,則會丟棄掉所有的數據。