{"id":103374,"date":"2026-09-10T11:09:09","date_gmt":"2026-09-10T03:09:09","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/103374.html"},"modified":"2026-09-10T11:09:09","modified_gmt":"2026-09-10T03:09:09","slug":"mmap%e7%9a%84%e7%9c%9f%e7%9b%b8%ef%bc%9a%e4%b8%8d%e6%8b%b7%e8%b4%9d%ef%bc%8c%e5%8f%aa%e6%98%a0%e5%b0%84","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/103374.html","title":{"rendered":"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04"},"content":{"rendered":"<h3>mmap \u7684\u5e95\u5c42\u771f\u76f8&#xff0c;\u4ee5\u53ca\u5c04\u51fb\u6e38\u620f\u91cc\u7684\u6bcf\u4e00\u6b21\u4ee3\u4ef7<\/h3>\n<hr \/>\n<h2>\u7b2c 0 \u7ae0&#xff1a;\u5148\u5efa\u7acb\u76f4\u89c9<\/h2>\n<h3>0.1 \u4e00\u4e2a\u6bd4\u55bb&#xff1a;\u540c\u4e00\u672c\u4e66&#xff0c;\u4e24\u4e2a\u95e8\u724c\u53f7<\/h3>\n<p>\u56fe\u4e66\u9986\u6709\u4e00\u672c\u4e66&#xff0c;\u7f16\u53f7 \u7269\u7406\u4e66\u67b6 P7\u3002<\/p>\n<p>\u8bfb\u8005 A \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;&#034;\u7b2c 3 \u53f7\u9605\u89c8\u684c&#034;<br \/>\n\u8bfb\u8005 B \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;&#034;\u7b2c 9 \u53f7\u9605\u89c8\u684c&#034;<br \/>\n\u56fe\u4e66\u9986\u7ba1\u7406\u7cfb\u7edf\u91cc\u8bb0\u7740&#xff1a; &#034;\u7269\u7406\u4e66\u67b6 P7&#034;<\/p>\n<p>\u4e09\u4e2a\u4e0d\u540c\u7684&#034;\u5730\u5740&#034;&#xff0c;\u6307\u5411\u540c\u4e00\u672c\u4e66\u3002<\/p>\n<p>\u8fd9\u5c31\u662f\u865a\u62df\u5185\u5b58&#xff1a;\u6bcf\u4e2a\u8fdb\u7a0b\u6709\u81ea\u5df1\u7684&#034;\u5730\u5740\u7c3f&#034;&#xff08;\u9875\u8868&#xff09;&#xff0c;\u4e0d\u540c\u7684\u865a\u62df\u5730\u5740\u53ef\u4ee5\u6620\u5c04\u5230\u540c\u4e00\u4e2a\u7269\u7406\u9875\u3002<\/p>\n<p>read() \u662f&#034;\u6284\u4e00\u4efd\u7ed9\u4f60&#034;&#xff0c;mmap() \u662f&#034;\u5728\u4f60\u7684\u5730\u5740\u7c3f\u4e0a\u52a0\u4e00\u6761&#xff0c;\u6307\u5411\u539f\u4e66&#034;\u3002<\/p>\n<h3>0.2 \u4e00\u53e5\u8bdd\u6982\u62ec\u672c\u6587\u8981\u8bb2\u7684\u4e1c\u897f<\/h3>\n<p>mmap \u4e0d\u642c\u6570\u636e&#xff0c;\u5b83\u53ea\u662f\u5f80\u4f60\u7684\u9875\u8868\u91cc\u5199\u4e86\u4e00\u884c&#xff0c;<br \/>\n\u8ba9\u67d0\u4e2a\u865a\u62df\u5730\u5740\u7684\u7ffb\u8bd1\u7ed3\u679c&#xff0c;\u843d\u5728 page cache \u5df2\u7ecf\u6301\u6709\u7684\u90a3\u4e2a\u7269\u7406\u9875\u5e27\u4e0a\u3002<\/p>\n<p>\u542c\u8d77\u6765\u7b80\u5355&#xff0c;\u4f46\u8fd9\u53e5\u8bdd\u91cc\u6bcf\u4e2a\u8bcd\u90fd\u6709\u5751\u3002\u4e0b\u9762\u9010\u5c42\u62c6\u5f00\u3002<\/p>\n<hr \/>\n<h2>\u7b2c 1 \u7ae0&#xff1a;\u4e09\u4e2a\u5fc5\u987b\u5148\u641e\u6e05\u7684\u6982\u5ff5<\/h2>\n<h3>1.1 \u8fdb\u7a0b\u770b\u5230\u7684\u5730\u5740\u5168\u662f\u5047\u7684<\/h3>\n<p><span class=\"token keyword\">byte<\/span><span class=\"token operator\">*<\/span> p <span class=\"token operator\">&#061;<\/span> <span class=\"token range operator\">..<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">;<\/span>                <span class=\"token comment\">\/\/ \u5047\u8bbe\u503c\u662f 0x7f8a3c000000<\/span><br \/>\nDebug<span class=\"token punctuation\">.<\/span><span class=\"token function\">Log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">ulong<\/span><span class=\"token punctuation\">)<\/span>p<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>          <span class=\"token comment\">\/\/ \u8fd9\u4e2a\u6570\u5b57\u5728\u7269\u7406\u5185\u5b58\u91cc\u6839\u672c\u4e0d\u5b58\u5728<\/span><\/p>\n<p>CPU \u6bcf\u6b21\u8bbf\u95ee\u5185\u5b58&#xff0c;\u90fd\u8981\u5148\u8ba9 MMU&#xff08;\u5185\u5b58\u7ba1\u7406\u5355\u5143&#xff09; \u628a\u865a\u62df\u5730\u5740\u7ffb\u8bd1\u6210\u7269\u7406\u5730\u5740\u3002\u7ffb\u8bd1\u89c4\u5219\u5b58\u5728\u9875\u8868\u91cc\u3002<\/p>\n<p>arm64 \u56db\u7ea7\u9875\u8868&#xff08;4KB \u9875&#xff09;&#xff1a;<\/p>\n<p>\u865a\u62df\u5730\u5740 48 \u4f4d&#xff1a;<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 9 bits \u2502 9 bits \u2502 9 bits \u2502 9 bits \u2502  12 bits   \u2502<br \/>\n\u2502  PGD   \u2502  PUD   \u2502  PMD   \u2502  PTE   \u2502  \u9875\u5185\u504f\u79fb   \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n                              \u2502<br \/>\n                              \u2514\u2500\u25b6 PTE \u91cc\u5b58\u7684\u662f\u3010\u7269\u7406\u9875\u5e27\u53f7 PFN\u3011&#043; \u6743\u9650\u4f4d<\/p>\n<p>\u7269\u7406\u5730\u5740 &#061; (PFN &lt;&lt; 12) | \u9875\u5185\u504f\u79fb<\/p>\n<p>\u5173\u952e&#xff1a;PTE&#xff08;\u9875\u8868\u9879&#xff09;\u91cc\u5b58\u7684\u662f\u7269\u7406\u9875\u5e27\u53f7\u3002\u8c01\u80fd\u6539 PTE&#xff0c;\u8c01\u5c31\u80fd\u51b3\u5b9a&#034;\u8fd9\u4e2a\u865a\u62df\u5730\u5740\u6307\u5411\u54ea\u5757\u7269\u7406\u5185\u5b58&#034;\u3002<\/p>\n<p>\u5185\u6838\u5c31\u662f\u9760\u6539 PTE \u5b9e\u73b0 mmap \u7684\u3002<\/p>\n<h3>1.2 Page Cache&#xff1a;\u6587\u4ef6\u5728\u5185\u5b58\u91cc\u7684\u90a3\u4efd\u526f\u672c<\/h3>\n<p>\u4f60\u8bfb\u4e00\u4e2a\u6587\u4ef6&#xff0c;\u6570\u636e\u4e0d\u4f1a\u6bcf\u6b21\u90fd\u4ece\u78c1\u76d8\u6765\u3002\u5185\u6838\u628a\u8bfb\u8fc7\u7684\u9875\u7f13\u5b58\u8d77\u6765&#xff1a;<\/p>\n<p>\u5185\u6838\u91cc\u7684\u7ed3\u6784&#xff1a;<\/p>\n<p>struct file \u2192 struct inode \u2192 struct address_space<br \/>\n                                     \u2502<br \/>\n                                     \u2514\u2500 i_pages&#xff08;XArray&#xff09;<br \/>\n                                        \u7d22\u5f15 &#061; \u6587\u4ef6\u5185\u9875\u53f7 (pgoff)<br \/>\n                                        \u503c   &#061; struct page*<\/p>\n<p>   pgoff 0 \u2192 page(PFN&#061;0x12345)<br \/>\n   pgoff 1 \u2192 page(PFN&#061;0x12346)<br \/>\n   pgoff 2 \u2192 &#xff08;\u4e0d\u5728&#xff0c;\u9700\u8981\u8bfb\u76d8&#xff09;<br \/>\n   pgoff 3 \u2192 page(PFN&#061;0x1AF20)<\/p>\n<p>Page Cache \u7684\u4e09\u4e2a\u6027\u8d28&#xff1a;<\/p>\n<table>\n<tr>\u6027\u8d28\u542b\u4e49<\/tr>\n<tbody>\n<tr>\n<td>\u5168\u5c40\u5171\u4eab<\/td>\n<td>\u4e00\u4e2a\u6587\u4ef6\u7684 page cache \u53ea\u6709\u4e00\u4efd&#xff0c;\u6240\u6709\u8fdb\u7a0b\u5171\u7528<\/td>\n<\/tr>\n<tr>\n<td>\u6309\u9875\u7ba1\u7406<\/td>\n<td>\u5355\u4f4d\u662f 4KB&#xff08;Android 15&#043; arm64 \u53ef\u80fd\u662f 16KB&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u56de\u6536<\/td>\n<td>\u5185\u5b58\u7d27\u5f20\u65f6&#xff0c;\u5e72\u51c0\u9875\u76f4\u63a5\u4e22&#xff0c;\u810f\u9875\u5148\u5199\u56de\u518d\u4e22<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>1.3 \u4e3a\u4ec0\u4e48 read() \u5fc5\u987b\u62f7\u8d1d<\/h3>\n<p><span class=\"token keyword\">char<\/span> buf<span class=\"token punctuation\">[<\/span><span class=\"token number\">4096<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token function\">read<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">,<\/span> buf<span class=\"token punctuation\">,<\/span> <span class=\"token number\">4096<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>buf \u662f\u4f60\u7684\u7528\u6237\u6001\u6808\/\u5806\u5185\u5b58&#xff0c;\u5b83\u5bf9\u5e94\u7684\u7269\u7406\u9875\u548c page cache \u7684\u7269\u7406\u9875\u662f\u4e24\u5757\u4e0d\u540c\u7684\u7269\u7406\u5185\u5b58\u3002<\/p>\n<p>\u7269\u7406\u5185\u5b58<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 PFN&#061;0x12345  \u2502 \u2190 page cache \u7684\u9875&#xff08;\u5185\u6838\u6301\u6709&#xff09;<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br \/>\n       \u2502 memcpy_to_user()  \u2605 \u4e00\u6b21\u771f\u5b9e\u7684 CPU \u62f7\u8d1d<br \/>\n       \u25bc<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502 PFN&#061;0x9ABCD  \u2502 \u2190 \u4f60\u7684 buf \u5bf9\u5e94\u7684\u9875<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>\u5185\u6838\u4e0d\u80fd\u628a buf \u7684 PTE \u76f4\u63a5\u6539\u6210\u6307\u5411 page cache&#xff0c;\u56e0\u4e3a&#xff1a;<\/p>\n<ul>\n<li>buf \u662f\u4f60\u5148\u5206\u914d\u7684&#xff0c;\u5b83\u5df2\u7ecf\u6709\u81ea\u5df1\u7684\u7269\u7406\u9875<\/li>\n<li>\u4f60\u53ef\u80fd\u968f\u610f\u6539 buf&#xff0c;\u6539\u4e86\u4e0d\u8be5\u5f71\u54cd\u6587\u4ef6\u5185\u5bb9<\/li>\n<li>buf \u53ef\u80fd\u4e0d\u662f\u9875\u5bf9\u9f50\u7684&#xff08;char buf[100]&#xff09;<\/li>\n<\/ul>\n<p>\u6240\u4ee5 read() \u5fc5\u987b\u62f7\u8d1d\u3002\u800c mmap \u4ece\u4e00\u5f00\u59cb\u5c31\u4e0d\u7ed9\u4f60\u5206\u914d\u7269\u7406\u9875&#xff0c;\u7b49\u4f60\u8bbf\u95ee\u65f6\u624d\u51b3\u5b9a\u6307\u5411\u54ea\u3002<\/p>\n<hr \/>\n<h2>\u7b2c 2 \u7ae0&#xff1a;mmap \u5230\u5e95\u505a\u4e86\u4ec0\u4e48&#xff08;\u51e0\u4e4e\u4ec0\u4e48\u90fd\u6ca1\u505a&#xff09;<\/h2>\n<h3>2.1 mmap \u8fd4\u56de\u65f6&#xff0c;\u9875\u8868\u662f\u7a7a\u7684<\/h3>\n<p><span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> p <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">8<\/span><span class=\"token operator\">*<\/span><span class=\"token number\">1024<\/span><span class=\"token operator\">*<\/span><span class=\"token number\">1024<\/span><span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token comment\">\/\/ \u6620\u5c04 8MB\u3002\u6b64\u65f6&#xff1a;<\/span><br \/>\n<span class=\"token comment\">\/\/   \u2705 \u5df2\u5efa\u7acb\u4e00\u4e2a vm_area_struct&#xff08;VMA&#xff09;<\/span><br \/>\n<span class=\"token comment\">\/\/   \u2705 \u5df2\u5212\u51fa\u4e00\u6bb5\u865a\u62df\u5730\u5740\u8303\u56f4<\/span><br \/>\n<span class=\"token comment\">\/\/   \u274c \u9875\u8868\u91cc 0 \u6761\u6709\u6548 PTE<\/span><br \/>\n<span class=\"token comment\">\/\/   \u274c \u78c1\u76d8 IO&#xff1a;0 \u6b21<\/span><br \/>\n<span class=\"token comment\">\/\/   \u274c \u7269\u7406\u5185\u5b58\u5206\u914d&#xff1a;0 \u5b57\u8282<\/span><\/p>\n<p>VMA \u662f\u4ec0\u4e48&#xff1a;\u5185\u6838\u91cc\u63cf\u8ff0&#034;\u8fd9\u6bb5\u865a\u62df\u5730\u5740\u662f\u5e72\u4ec0\u4e48\u7528\u7684&#034;\u7684\u5143\u6570\u636e\u3002<\/p>\n<p><span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">vm_area_struct<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">long<\/span> vm_start<span class=\"token punctuation\">,<\/span> vm_end<span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u865a\u62df\u5730\u5740\u8303\u56f4<\/span><br \/>\n    <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">file<\/span> <span class=\"token operator\">*<\/span>vm_file<span class=\"token punctuation\">;<\/span>             <span class=\"token comment\">\/\/ \u2605 \u5173\u8054\u54ea\u4e2a\u6587\u4ef6<\/span><br \/>\n    <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">long<\/span> vm_pgoff<span class=\"token punctuation\">;<\/span>           <span class=\"token comment\">\/\/ \u2605 \u4ece\u6587\u4ef6\u7b2c\u51e0\u9875\u5f00\u59cb<\/span><br \/>\n    <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">long<\/span> vm_flags<span class=\"token punctuation\">;<\/span>           <span class=\"token comment\">\/\/ VM_SHARED \/ VM_READ \/ VM_WRITE<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">vm_operations_struct<\/span> <span class=\"token operator\">*<\/span>vm_ops<span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u2605 \u7f3a\u9875\u65f6\u8c03\u8c01<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>mmap \u7684\u5168\u90e8\u5de5\u4f5c &#061; \u9020\u4e00\u4e2a VMA&#xff0c;\u63d2\u8fdb\u7ea2\u9ed1\u6811&#xff0c;\u8fd4\u56de\u5730\u5740\u3002<\/p>\n<p>\u8017\u65f6\u7ea6 1~10 \u5fae\u79d2&#xff0c;\u548c\u6587\u4ef6\u5927\u5c0f\u65e0\u5173\u3002\u6620\u5c04 8MB \u548c\u6620\u5c04 8GB \u4e00\u6837\u5feb\u3002<\/p>\n<h3>2.2 \u7b2c\u4e00\u6b21\u8bbf\u95ee&#xff1a;\u7f3a\u9875\u5f02\u5e38\u7684\u5b8c\u6574\u6d41\u7a0b<\/h3>\n<p><span class=\"token keyword\">char<\/span> c <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">char<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span>p<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span>    <span class=\"token comment\">\/\/ \u5c31\u8fd9\u4e00\u884c&#xff0c;\u89e6\u53d1\u4e0b\u9762\u5168\u90e8\u6d41\u7a0b<\/span><\/p>\n<p>\u2460 CPU \u53d1\u51fa\u865a\u62df\u5730\u5740 \u2192 MMU \u67e5\u9875\u8868<br \/>\n     PTE \u65e0\u6548&#xff08;present \u4f4d\u4e3a 0&#xff09;<br \/>\n        \u2193<br \/>\n\u2461 CPU \u629b\u51fa\u540c\u6b65\u5f02\u5e38&#xff08;arm64: Data Abort&#xff09;<br \/>\n     \u5207\u5230\u5185\u6838\u6001&#xff0c;\u8fdb\u5165 do_page_fault()<br \/>\n        \u2193<br \/>\n\u2462 \u5728\u5f53\u524d\u8fdb\u7a0b\u7684 VMA \u7ea2\u9ed1\u6811\u91cc\u627e&#xff1a;&#034;\u8fd9\u4e2a\u5730\u5740\u5c5e\u4e8e\u54ea\u4e2a VMA&#xff1f;&#034;<br \/>\n     \u627e\u4e0d\u5230 \u2192 SIGSEGV&#xff08;\u6bb5\u9519\u8bef&#xff09;<br \/>\n     \u627e\u5230\u4e86 \u2192 \u68c0\u67e5\u6743\u9650&#xff08;\u5199\u53ea\u8bfb\u533a \u2192 SIGSEGV&#xff09;<br \/>\n        \u2193<br \/>\n\u2463 handle_mm_fault() \u2192 \u5224\u65ad VMA \u7c7b\u578b<br \/>\n     vm_file !&#061; NULL \u2192 \u6587\u4ef6\u6620\u5c04&#xff0c;\u8c03 vma-&gt;vm_ops-&gt;fault<br \/>\n                        \u5bf9\u666e\u901a\u6587\u4ef6\u5c31\u662f filemap_fault()<br \/>\n        \u2193<br \/>\n\u2464 filemap_fault()&#xff1a;\u7b97\u51fa\u6587\u4ef6\u5185\u9875\u53f7<br \/>\n     pgoff &#061; vm_pgoff &#043; (addr &#8211; vm_start) \/ PAGE_SIZE<\/p>\n<p>     \u5728 address_space \u7684 XArray \u91cc\u67e5 pgoff&#xff1a;<br \/>\n     \u251c\u2500 \u547d\u4e2d  \u2192 \u2605 Minor Fault&#xff0c;\u8df3\u5230 \u2466<br \/>\n     \u2514\u2500 \u672a\u547d\u4e2d \u2192 \u2605 Major Fault&#xff0c;\u8d70 \u2465<br \/>\n        \u2193<br \/>\n\u2465 \u3010Major Fault\u3011<br \/>\n     a. \u5206\u914d\u4e00\u4e2a\u7269\u7406\u9875<br \/>\n     b. \u6302\u8fdb page cache&#xff08;XArray[pgoff] &#061; page&#xff09;<br \/>\n     c. \u63d0\u4ea4\u8bfb IO&#xff0c;\u628a\u8fd9\u4e00\u9875\u586b\u4e0a<br \/>\n     d. \u2605 \u5f53\u524d\u7ebf\u7a0b\u7761\u7720\u7b49 IO \u5b8c\u6210&#xff08;\u8fd9\u5c31\u662f\u5361\u987f\u6765\u6e90&#xff09;<br \/>\n        \u2193<br \/>\n\u2466 \u5efa\u7acb PTE<br \/>\n     pfn &#061; page_to_pfn(page);           \/\/ \u2605 page cache \u90a3\u4e00\u9875\u7684\u7269\u7406\u9875\u5e27\u53f7<br \/>\n     set_pte_at(mm, addr, ptep, mk_pte(page, prot));<br \/>\n     page-&gt;_mapcount&#043;&#043;;                 \/\/ \u8bb0\u5f55&#034;\u591a\u4e86\u4e00\u4e2a\u8fdb\u7a0b\u6620\u5c04\u6211&#034;<br \/>\n        \u2193<br \/>\n\u2467 \u4ece\u5f02\u5e38\u8fd4\u56de&#xff0c;CPU \u91cd\u65b0\u6267\u884c\u90a3\u6761 load \u6307\u4ee4<br \/>\n     \u8fd9\u6b21 MMU \u7ffb\u8bd1\u6210\u529f&#xff0c;\u8bfb\u5230\u6570\u636e<\/p>\n<h3>2.3 \u5173\u952e\u7684\u4e00\u53e5&#xff1a;PTE \u6307\u5411\u7684\u5c31\u662f page cache \u7684\u9875<\/h3>\n<p>\u7b2c \u2466 \u6b65\u662f\u672c\u6587\u6807\u9898\u7684\u7b54\u6848&#xff1a;<\/p>\n<p>pfn <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">page_to_pfn<\/span><span class=\"token punctuation\">(<\/span>page<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>page \u662f\u4ece page cache \u7684 XArray \u91cc\u62ff\u51fa\u6765\u7684 struct page*\u3002\u5b83\u7684\u7269\u7406\u9875\u5e27\u53f7\u88ab\u76f4\u63a5\u5199\u8fdb\u4e86\u4f60\u7684 PTE\u3002<\/p>\n<p>\u4ece\u8fd9\u4e00\u523b\u8d77&#xff1a;<\/p>\n<p>\u4f60\u7684\u865a\u62df\u5730\u5740 p&#043;0<br \/>\n        \u2502 MMU \u7ffb\u8bd1<br \/>\n        \u25bc<br \/>\n   \u7269\u7406\u9875 PFN&#061;0x12345<br \/>\n        \u25b2<br \/>\n        \u2502 page cache \u7684 XArray[0] \u4e5f\u6307\u5411\u5b83<br \/>\n   \u5185\u6838 address_space<\/p>\n<p>\u2192 \u540c\u4e00\u5757\u7269\u7406\u5185\u5b58&#xff0c;\u4e24\u4e2a&#034;\u540d\u5b57&#034;<br \/>\n\u2192 \u4f60\u8bfb\u5b83&#xff0c;\u5c31\u662f\u8bfb page cache<br \/>\n\u2192 \u4f60\u5199\u5b83&#xff08;MAP_SHARED&#xff09;&#xff0c;\u5c31\u662f\u6539 page cache<\/p>\n<h3>2.4 \u4e00\u4e2a\u91cd\u8981\u4f18\u5316&#xff1a;Fault-Around<\/h3>\n<p>\u5982\u679c\u6bcf\u8bbf\u95ee 4KB \u5c31\u5f02\u5e38\u4e00\u6b21&#xff0c;8MB \u6587\u4ef6\u8981 2048 \u6b21\u5f02\u5e38&#xff0c;\u592a\u6162\u3002<\/p>\n<p>\u5185\u6838\u505a\u4e86 fault-around&#xff1a;\u4e00\u6b21 minor fault&#xff0c;\u987a\u4fbf\u628a\u5468\u56f4\u5df2\u5728 page cache \u7684\u9875\u4e00\u8d77\u5efa PTE\u3002<\/p>\n<p><span class=\"token comment\">\/\/ mm\/memory.c<\/span><br \/>\n<span class=\"token keyword\">static<\/span> <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">long<\/span> fault_around_bytes __read_mostly <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">65536<\/span><span class=\"token punctuation\">;<\/span>  <span class=\"token comment\">\/\/ 16 \u9875<\/span><\/p>\n<p><span class=\"token function\">do_fault_around<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span><br \/>\n    \u4ee5\u51fa\u9519\u5730\u5740\u4e3a\u4e2d\u5fc3&#xff0c;\u5411\u524d\u540e\u6269\u5c55\u5230 <span class=\"token number\">64<\/span>KB \u8fb9\u754c<br \/>\n    \u5bf9\u6bcf\u4e00\u9875&#xff1a;\u5982\u679c\u5728 page cache \u91cc \u2192 \u4e00\u8d77\u5efa PTE<\/p>\n<p>\u6548\u679c&#xff1a;\u987a\u5e8f\u8bbf\u95ee\u4e00\u4e2a\u5df2\u7f13\u5b58\u7684\u6587\u4ef6&#xff0c;\u7f3a\u9875\u6b21\u6570\u964d\u5230 1\/16\u3002<\/p>\n<p>\u8fd9\u89e3\u91ca\u4e86\u4e00\u4e2a\u73b0\u8c61&#xff1a;\u9884\u70ed\u8fc7\u7684 bundle&#xff0c;\u52a0\u8f7d\u65f6\u51e0\u4e4e\u770b\u4e0d\u5230 fault&#xff1b;\u6ca1\u9884\u70ed\u7684&#xff0c;fault \u6570\u91cf\u60ca\u4eba\u3002\u56e0\u4e3a fault-around \u53ea\u6620\u5c04\u5df2\u5728\u7f13\u5b58\u7684\u9875&#xff0c;\u7f13\u5b58\u91cc\u6ca1\u6709\u7684\u8bdd\u5b83\u5e2e\u4e0d\u4e0a\u5fd9\u3002<\/p>\n<hr \/>\n<h2>\u7b2c 3 \u7ae0&#xff1a;\u5171\u4eab vs \u79c1\u6709&#xff0c;\u4ee5\u53ca\u5199\u5165\u7684\u4ee3\u4ef7<\/h2>\n<h3>3.1 MAP_SHARED&#xff1a;\u771f\u6b63\u7684\u5171\u4eab<\/h3>\n<p><span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token operator\">|<\/span>PROT_WRITE<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u8fdb\u7a0b A \u7684 PTE \u2500\u2500\u2510<br \/>\n                \u251c\u2500\u2500\u25b6 \u7269\u7406\u9875 PFN&#061;0x12345 \u25c0\u2500\u2500 page cache<br \/>\n\u8fdb\u7a0b B \u7684 PTE \u2500\u2500\u2518<\/p>\n<p>\u5199\u5165 \u2192 \u76f4\u63a5\u6539\u8fd9\u5757\u7269\u7406\u5185\u5b58<br \/>\n     \u2192 PTE \u7684 dirty \u4f4d\u7f6e 1<br \/>\n     \u2192 \u5185\u6838\u6807\u8bb0 page \u4e3a PageDirty<br \/>\n     \u2192 writeback \u7ebf\u7a0b\u7a0d\u540e\u5199\u56de\u6587\u4ef6<\/p>\n<p>\u4e09\u4e2a\u63a8\u8bba&#xff08;\u90fd\u5f88\u91cd\u8981&#xff09;&#xff1a;<\/p>\n<li>A \u5199\u7684\u5185\u5bb9 B \u7acb\u523b\u770b\u5f97\u5230&#xff08;\u540c\u4e00\u5757\u7269\u7406\u5185\u5b58&#xff0c;\u65e0\u9700\u4efb\u4f55\u540c\u6b65\u673a\u5236&#xff09;<\/li>\n<li>\u5185\u5bb9\u4f1a\u843d\u5230\u6587\u4ef6\u91cc&#xff08;\u8fd9\u662f\u6301\u4e45\u5316\u7684\u57fa\u7840&#xff09;<\/li>\n<li>\u8fdb\u7a0b\u88ab SIGKILL \u4e5f\u4e0d\u4e22&#xff08;\u810f\u9875\u5728\u5185\u6838&#xff0c;\u8fdb\u7a0b\u6b7b\u4e86\u5185\u6838\u7167\u6837\u5199\u56de&#xff09;<\/li>\n<h3>3.2 MAP_PRIVATE&#xff1a;\u5199\u65f6\u590d\u5236\u7684\u9677\u9631<\/h3>\n<p><span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token operator\">|<\/span>PROT_WRITE<span class=\"token punctuation\">,<\/span> MAP_PRIVATE<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u3010\u8bfb\u9636\u6bb5\u3011\u548c SHARED \u4e00\u6837&#xff0c;PTE \u6307\u5411 page cache&#xff0c;\u4f46\u6807\u8bb0\u4e3a\u53ea\u8bfb<\/p>\n<p>\u3010\u7b2c\u4e00\u6b21\u5199\u3011<br \/>\n   \u2460 \u5199\u53ea\u8bfb PTE \u2192 \u89e6\u53d1\u5199\u4fdd\u62a4\u7f3a\u9875<br \/>\n   \u2461 do_wp_page()&#xff1a;\u5206\u914d\u4e00\u4e2a\u65b0\u7684\u533f\u540d\u9875<br \/>\n   \u2462 \u628a page cache \u90a3\u9875\u7684\u5185\u5bb9 memcpy \u8fc7\u53bb    \u2605 \u4e00\u6b21\u771f\u5b9e\u62f7\u8d1d<br \/>\n   \u2463 PTE \u6539\u6307\u5411\u65b0\u9875&#xff0c;\u6807\u8bb0\u53ef\u5199<br \/>\n   \u2464 \u4ece\u6b64\u8fd9\u4e00\u9875\u548c\u6587\u4ef6\u3001\u548c page cache \u5b8c\u5168\u8131\u94a9<\/p>\n<p>\u5c04\u51fb\u6e38\u620f\u91cc\u7684\u771f\u5b9e\u4e8b\u6545&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u67d0\u9879\u76ee\u7528 MAP_PRIVATE \u6620\u5c04\u4e86 200MB \u7684\u5730\u56fe\u6570\u636e<\/span><br \/>\n<span class=\"token comment\">\/\/ \u7136\u540e\u5728\u52a0\u8f7d\u65f6\u505a\u4e86&#034;\u539f\u5730\u4fee\u6b63\u5750\u6807&#034;<\/span><br \/>\n<span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">int<\/span><\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;<\/span> vertexCount<span class=\"token punctuation\">;<\/span> i<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    vertices<span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>y <span class=\"token operator\">&#043;&#061;<\/span> terrainOffset<span class=\"token punctuation\">;<\/span>      <span class=\"token comment\">\/\/ \u274c \u6bcf\u5199\u4e00\u9875\u89e6\u53d1 COW<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7ed3\u679c&#xff1a;<\/span><br \/>\n<span class=\"token comment\">\/\/   \u6620\u5c04\u65f6 PSS \u589e\u91cf \u2248 0<\/span><br \/>\n<span class=\"token comment\">\/\/   \u904d\u5386\u5b8c\u6210\u540e PSS \u589e\u91cf &#061; 200 MB&#xff08;\u5168\u90e8 COW \u6210\u533f\u540d\u9875&#xff09;<\/span><br \/>\n<span class=\"token comment\">\/\/   \u800c\u4e14\u533f\u540d\u9875\u4e0d\u80fd\u88ab\u76f4\u63a5\u56de\u6536&#xff0c;\u53ea\u80fd swap&#xff08;Android \u4e0a\u6ca1 swap \u2192 \u76f4\u63a5 OOM&#xff09;<\/span><\/p>\n<table>\n<tr>MAP_SHAREDMAP_PRIVATE<\/tr>\n<tbody>\n<tr>\n<td>\u8bfb<\/td>\n<td>\u6307\u5411 page cache<\/td>\n<td>\u6307\u5411 page cache<\/td>\n<\/tr>\n<tr>\n<td>\u5199<\/td>\n<td>\u6539 page cache<\/td>\n<td>COW \u51fa\u533f\u540d\u9875<\/td>\n<\/tr>\n<tr>\n<td>\u5185\u5b58\u5f52\u7c7b<\/td>\n<td>file-backed&#xff0c;\u53ef\u76f4\u63a5\u56de\u6536<\/td>\n<td>anon&#xff0c;\u53ea\u80fd swap<\/td>\n<\/tr>\n<tr>\n<td>\u4f1a\u5199\u56de\u6587\u4ef6<\/td>\n<td>\u2705<\/td>\n<td>\u274c<\/td>\n<\/tr>\n<tr>\n<td>\u9002\u7528<\/td>\n<td>\u8bfb\u5199\u5171\u4eab\u6570\u636e\u3001\u65e5\u5fd7\u3001\u5f55\u50cf<\/td>\n<td>\u53ea\u8bfb\u4e3a\u4e3b\u7684\u8d44\u6e90<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&#x1f4cc; \u89c4\u5219&#xff1a;\u53ea\u8bfb\u8d44\u6e90\u7528 MAP_PRIVATE \u4e14\u7edd\u4e0d\u5199\u5165&#xff1b;\u8981\u5199\u5c31\u7528 MAP_SHARED\u3002 \u6df7\u7740\u6765\u5fc5\u7136\u51fa\u4e8b\u3002<\/p>\n<hr \/>\n<h2>\u7b2c 4 \u7ae0&#xff1a;\u5185\u5b58\u538b\u529b\u4e0b\u4f1a\u53d1\u751f\u4ec0\u4e48&#xff08;\u6700\u5bb9\u6613\u88ab\u5ffd\u7565&#xff09;<\/h2>\n<h3>4.1 mmap \u7684\u9875\u4e5f\u4f1a\u88ab\u56de\u6536<\/h3>\n<p>\u5f88\u591a\u4eba\u4ee5\u4e3a mmap \u4e4b\u540e\u9875\u5c31&#034;\u9489\u4f4f&#034;\u4e86\u3002\u4e0d\u662f\u7684\u3002<\/p>\n<p>\u5185\u6838 LRU \u94fe\u8868&#xff1a;<br \/>\n  \u251c\u2500 active_file    \u2190 \u6700\u8fd1\u8bbf\u95ee\u8fc7\u7684\u6587\u4ef6\u9875<br \/>\n  \u251c\u2500 inactive_file  \u2190 \u51b7\u7684\u6587\u4ef6\u9875<br \/>\n  \u251c\u2500 active_anon<br \/>\n  \u2514\u2500 inactive_anon<\/p>\n<p>\u5185\u5b58\u4e0d\u8db3\u65f6&#xff0c;kswapd \/ direct reclaim \u4ece inactive \u5c3e\u90e8\u5f00\u5200&#xff1a;<\/p>\n<p>\u5e72\u51c0\u7684\u6587\u4ef6\u9875&#xff08;clean file page&#xff09;<br \/>\n   \u2192 \u2605 \u76f4\u63a5 free&#xff0c;\u96f6\u6210\u672c&#xff08;\u5185\u5bb9\u548c\u78c1\u76d8\u4e00\u81f4&#xff09;<br \/>\n   \u2192 \u6e05\u6389\u6240\u6709\u6307\u5411\u5b83\u7684 PTE<\/p>\n<p>\u810f\u7684\u6587\u4ef6\u9875&#xff08;dirty&#xff09;<br \/>\n   \u2192 \u5148\u5199\u56de\u6587\u4ef6&#xff0c;\u518d free<\/p>\n<p>\u533f\u540d\u9875&#xff08;anon&#xff09;<br \/>\n   \u2192 \u9700\u8981 swap&#xff1b;Android \u901a\u5e38\u65e0 swap \u5206\u533a<br \/>\n   \u2192 \u53ea\u80fd\u9760 zram \u538b\u7f29&#xff0c;\u6216\u8005\u2026\u2026\u6740\u8fdb\u7a0b<\/p>\n<p>\u63a8\u8bba 1&#xff08;\u597d\u6d88\u606f&#xff09;&#xff1a;mmap \u7684\u53ea\u8bfb\u8d44\u6e90\u662f\u7cfb\u7edf\u773c\u91cc\u6700\u4fbf\u5b9c\u7684\u5185\u5b58\u3002<\/p>\n<p>\u63a8\u8bba 2&#xff08;\u574f\u6d88\u606f&#xff09;&#xff1a;\u88ab\u56de\u6536\u7684\u9875\u518d\u8bbf\u95ee&#xff0c;\u53c8\u662f\u4e00\u6b21 major fault\u3002<\/p>\n<h3>4.2 \u8fd9\u5c31\u662f&#034;\u5185\u5b58\u538b\u529b\u4e0b\u7684\u6296\u52a8&#034;<\/h3>\n<p>\u5c04\u51fb\u6e38\u620f\u5728 4GB \u5185\u5b58\u673a\u5668\u4e0a&#xff0c;\u7528\u6237\u540e\u53f0\u8fd8\u5f00\u7740\u5fae\u4fe1&#xff1a;<\/p>\n<p>  T0&#xff1a;\u52a0\u8f7d\u5b8c\u5730\u56fe&#xff0c;8MB bundle \u7684\u9875\u5168\u5728 page cache<br \/>\n  T1&#xff1a;\u73a9\u5bb6\u5207\u540e\u53f0\u770b\u4e86\u773c\u5fae\u4fe1<br \/>\n  T2&#xff1a;\u5fae\u4fe1\u8981\u5185\u5b58 \u2192 kswapd \u56de\u6536\u5e72\u51c0\u6587\u4ef6\u9875<br \/>\n      \u2192 \u4f60\u7684 bundle \u9875\u88ab\u56de\u6536&#xff08;\u56e0\u4e3a\u5b83\u4eec\u6700&#034;\u4fbf\u5b9c&#034;&#xff09;<br \/>\n  T3&#xff1a;\u73a9\u5bb6\u5207\u56de\u6765 \u2192 \u91cd\u65b0\u8bbf\u95ee\u6a21\u578b\u6570\u636e<br \/>\n      \u2192 \u2605 major fault \u98ce\u66b4&#xff0c;\u5361 200ms<\/p>\n<p>\u8fd9\u5c31\u662f&#034;\u5207\u540e\u53f0\u518d\u56de\u6765\u4f1a\u5361&#034;\u7684\u5e95\u5c42\u539f\u56e0\u4e4b\u4e00\u3002<\/p>\n<h3>4.3 mlock&#xff1a;\u9489\u4f4f\u9875\u7684\u4ee3\u4ef7<\/h3>\n<p><span class=\"token function\">mlock<\/span><span class=\"token punctuation\">(<\/span>addr<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>          <span class=\"token comment\">\/\/ \u5f3a\u5236\u8fd9\u6bb5\u9875\u5e38\u9a7b&#xff0c;\u4e0d\u8bb8\u56de\u6536<\/span><\/p>\n<p>\u80fd\u89e3\u51b3\u6296\u52a8&#xff0c;\u4f46&#xff1a;<\/p>\n<p>\u2460 RLIMIT_MEMLOCK \u9650\u5236&#xff08;Android \u4e0a\u901a\u5e38\u5f88\u5c0f&#xff0c;\u9700\u8981\u7279\u6743&#xff09;<br \/>\n\u2461 \u88ab mlock \u7684\u9875\u5bf9 LMK \u6765\u8bf4\u662f&#034;\u4e0d\u53ef\u56de\u6536\u5185\u5b58&#034;<br \/>\n   \u2192 \u4f60\u7684 oom_score \u53d8\u9ad8<br \/>\n   \u2192 \u2605 \u7cfb\u7edf\u4e0d\u56de\u6536\u4f60\u7684\u9875&#xff0c;\u6539\u4e3a\u76f4\u63a5\u6740\u4f60\u7684\u8fdb\u7a0b<br \/>\n\u2462 \u76f8\u5f53\u4e8e\u628a&#034;\u5c40\u90e8\u5361\u987f&#034;\u6362\u6210&#034;\u6574\u4f53\u95ea\u9000&#034;<\/p>\n<p>\u66f4\u5b9e\u7528\u7684\u66ff\u4ee3\u65b9\u6848&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u6e29\u548c\u7684\u5efa\u8bae&#xff1a;\u544a\u8bc9\u5185\u6838&#034;\u8fd9\u6bb5\u6211\u5f88\u5feb\u8981\u7528&#xff0c;\u5c3d\u91cf\u7559\u7740&#034;<\/span><br \/>\n<span class=\"token function\">madvise<\/span><span class=\"token punctuation\">(<\/span>addr<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">,<\/span> MADV_WILLNEED<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u544a\u8bc9\u5185\u6838&#034;\u8fd9\u6bb5\u6211\u968f\u673a\u8bbf\u95ee&#xff0c;\u522b\u505a\u987a\u5e8f\u9884\u8bfb&#034;<\/span><br \/>\n<span class=\"token function\">madvise<\/span><span class=\"token punctuation\">(<\/span>addr<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">,<\/span> MADV_RANDOM<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u544a\u8bc9\u5185\u6838&#034;\u8fd9\u6bb5\u6211\u4e0d\u9700\u8981\u4e86&#xff0c;\u968f\u4fbf\u56de\u6536&#034;&#xff08;\u5173\u5361\u5207\u6362\u65f6\u7528&#xff09;<\/span><br \/>\n<span class=\"token function\">madvise<\/span><span class=\"token punctuation\">(<\/span>addr<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">,<\/span> MADV_DONTNEED<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u26a0\ufe0f MAP_PRIVATE \u4e0b\u4f1a\u4e22\u5f03 COW \u7684\u4fee\u6539&#xff01;<\/span><\/p>\n<h3>4.4 PSS \u662f\u600e\u4e48\u7b97\u7684<\/h3>\n<p>Android \u7684 dumpsys meminfo \u663e\u793a\u7684 PSS&#xff08;Proportional Set Size&#xff09;&#xff1a;<\/p>\n<p>\u4e00\u4e2a\u7269\u7406\u9875\u88ab N \u4e2a\u8fdb\u7a0b\u6620\u5c04 \u2192 \u6bcf\u4e2a\u8fdb\u7a0b\u7b97 1\/N \u9875<\/p>\n<p>\u4f8b&#xff1a;libunity.so \u7684 .text \u6bb5\u88ab 3 \u4e2a\u8fdb\u7a0b\u6620\u5c04<br \/>\n    \u2192 \u6bcf\u4e2a\u8fdb\u7a0b\u7684 PSS \u53ea\u8ba1\u5165 1\/3<\/p>\n<p>mmap \u4e00\u4e2a\u53ea\u6709\u81ea\u5df1\u5728\u7528\u7684 bundle<br \/>\n    \u2192 mapcount &#061; 1 \u2192 PSS \u5168\u989d\u8ba1\u5165<\/p>\n<p>\u2605 \u4f46\u53ea\u6709\u3010\u5b9e\u9645 fault \u8fdb\u6765\u7684\u9875\u3011\u624d\u8ba1\u5165<br \/>\n  \u6620\u5c04\u4e86 8MB \u4f46\u53ea\u8bbf\u95ee\u4e86 1MB \u2192 PSS \u53ea\u589e 1MB<\/p>\n<p>\u8fd9\u5c31\u662f LoadFromFile \u6bd4 LoadFromMemory \u5185\u5b58\u4f4e 10 \u500d\u7684\u771f\u6b63\u539f\u56e0&#xff1a;\u4e0d\u662f&#034;\u66f4\u7701&#034;&#xff0c;\u800c\u662f\u5f88\u591a\u9875\u4ece\u6765\u6ca1\u88ab\u8bbf\u95ee\u8fc7&#xff0c;\u6240\u4ee5\u4ece\u6765\u6ca1\u88ab fault \u8fdb\u6765\u3002<\/p>\n<hr \/>\n<h2>\u7b2c 5 \u7ae0&#xff1a;Android \u7684\u7279\u6b8a\u60c5\u51b5<\/h2>\n<h3>5.1 APK \u5185 mmap \u4e0e\u9875\u5bf9\u9f50<\/h3>\n<p>Unity \u5728 Android \u4e0a\u53ef\u4ee5\u76f4\u63a5 mmap APK \u91cc\u7684 bundle&#xff1a;<\/p>\n<p><span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> ab <span class=\"token operator\">&#061;<\/span> AssetBundle<span class=\"token punctuation\">.<\/span><span class=\"token function\">LoadFromFile<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    Path<span class=\"token punctuation\">.<\/span><span class=\"token function\">Combine<\/span><span class=\"token punctuation\">(<\/span>Application<span class=\"token punctuation\">.<\/span>streamingAssetsPath<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;aa\/Android\/base.bundle&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u80fd\u6210\u7acb\u7684\u4e24\u4e2a\u786c\u6761\u4ef6&#xff1a;<\/p>\n<p>\u2460 \u8be5 ZIP \u6761\u76ee\u5fc5\u987b\u662f STORED&#xff08;\u4e0d\u538b\u7f29&#xff09;<br \/>\n   \u2192 \u53ea\u6709\u539f\u6837\u5b58\u653e&#xff0c;\u6587\u4ef6\u5185\u504f\u79fb\u624d\u5bf9\u5e94\u8fde\u7eed\u7684\u5b57\u8282\u6d41<br \/>\n   \u2192 Deflate \u538b\u7f29\u7684\u6761\u76ee\u65e0\u6cd5 mmap&#xff0c;\u5fc5\u987b\u5168\u91cf\u89e3\u538b<\/p>\n<p>\u2461 mmap \u7684 offset \u5fc5\u987b\u9875\u5bf9\u9f50<br \/>\n   \u2192 mmap(fd, offset) \u8981\u6c42 offset % PAGE_SIZE &#061;&#061; 0<br \/>\n   \u2192 \u6240\u4ee5 zipalign \u5b58\u5728\u7684\u610f\u4e49\u5c31\u662f\u8ba9\u6761\u76ee\u8d77\u59cb\u4f4d\u7f6e\u5bf9\u9f50<\/p>\n<p><span class=\"token comment\"># \u9a8c\u8bc1<\/span><br \/>\nadb shell pm path com.xxx.game<br \/>\nadb pull \/data\/app\/<span class=\"token punctuation\">..<\/span>.\/base.apk<br \/>\n<span class=\"token function\">unzip<\/span> <span class=\"token parameter variable\">-v<\/span> base.apk <span class=\"token operator\">|<\/span> <span class=\"token function\">grep<\/span> <span class=\"token parameter variable\">-E<\/span> <span class=\"token string\">&#034;bundle|\\\\.so&#034;<\/span><\/p>\n<p>  8452096  Stored   8452096   0%  assets\/aa\/Android\/base.bundle   \u2190 \u2705 \u53ef mmap<br \/>\n 24336384  Stored  24336384   0%  lib\/arm64-v8a\/libil2cpp.so      \u2190 \u2705 \u53ef mmap<br \/>\n  4231680  Defl:N   1892304  55%  assets\/config\/weapons.json      \u2190 \u274c \u9700\u89e3\u538b<\/p>\n<p>Android 15 \u8d77 arm64 \u652f\u6301 16KB \u9875&#xff0c;\u5bf9\u9f50\u8981\u6c42\u53d8\u6210 16KB&#xff1a;<\/p>\n<p>android {<br \/>\n    \/\/ \u4fdd\u8bc1 bundle \u4e0d\u88ab\u538b\u7f29<br \/>\n    aaptOptions { noCompress &#039;.bundle&#039;, &#039;.unity3d&#039;, &#039;.resS&#039;, &#039;.resource&#039; }<br \/>\n    \/\/ \u4fdd\u8bc1 so 16KB \u5bf9\u9f50&#xff08;NDK r27&#043; \/ AGP 8.5&#043;&#xff09;<br \/>\n    packagingOptions { jniLibs { useLegacyPackaging false } }<br \/>\n}<\/p>\n<h3>5.2 \u5916\u90e8\u5b58\u50a8\u7684 FUSE \u60e9\u7f5a<\/h3>\n<p>\/data\/data\/\u5305\u540d\/files\/x.bundle<br \/>\n   \u2192 ext4\/f2fs&#xff0c;mmap \u7684 major fault \u8d70\u6807\u51c6\u5757\u8bbe\u5907\u8def\u5f84<br \/>\n   \u2192 \u4e00\u6b21 fault \u2248 100 \u03bcs<\/p>\n<p>\/storage\/emulated\/0\/Android\/data\/\u5305\u540d\/files\/x.bundle<br \/>\n   \u2192 \u2605 FUSE \u865a\u62df\u6587\u4ef6\u7cfb\u7edf&#xff0c;\u8f6c\u53d1\u5230 \/data\/media\/0<br \/>\n   \u2192 major fault \u9700\u8981 upcall \u5230\u7528\u6237\u6001 daemon \u518d\u56de\u6765<br \/>\n   \u2192 \u4e00\u6b21 fault \u2248 200~500 \u03bcs<\/p>\n<p>\u7ed3\u8bba&#xff1a;mmap \u5bc6\u96c6\u8bbf\u95ee\u7684\u6587\u4ef6\u5fc5\u987b\u653e\u5185\u90e8\u5b58\u50a8\u3002 \u5916\u90e8\u5b58\u50a8\u53ea\u653e\u4f4e\u9891\u5927\u6587\u4ef6\u3002<\/p>\n<h3>5.3 \u533f\u540d\u5171\u4eab\u5185\u5b58&#xff1a;ashmem \/ memfd<\/h3>\n<p>\u8de8\u8fdb\u7a0b\u5171\u4eab\u7528\u4e0d\u4e86\u666e\u901a\u6587\u4ef6&#xff0c;\u7528\u533f\u540d\u5171\u4eab\u5185\u5b58&#xff1a;<\/p>\n<p><span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;android\/sharedmem.h&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u4e3b\u8fdb\u7a0b<\/span><br \/>\n<span class=\"token keyword\">int<\/span> fd <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ASharedMemory_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;replay_ring&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">8<\/span><span class=\"token operator\">*<\/span><span class=\"token number\">1024<\/span><span class=\"token operator\">*<\/span><span class=\"token number\">1024<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> base <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> size<span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token operator\">|<\/span>PROT_WRITE<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token comment\">\/\/ \u901a\u8fc7 Binder \u628a fd \u4f20\u7ed9\u5f55\u5236\u8fdb\u7a0b<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5f55\u5236\u8fdb\u7a0b\u6536\u5230 fd \u540e<\/span><br \/>\n<span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> base2 <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> size<span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token comment\">\/\/ \u2605 base \u548c base2 \u662f\u4e0d\u540c\u7684\u865a\u62df\u5730\u5740&#xff0c;\u6307\u5411\u540c\u4e00\u6279\u7269\u7406\u9875<\/span><\/p>\n<p>\u6ce8\u610f&#xff1a;\u8fd9\u7c7b\u5185\u5b58\u4e0d backed by \u6587\u4ef6&#xff0c;\u662f\u533f\u540d\u9875\u3002\u6240\u4ee5&#xff1a;<\/p>\n<ul>\n<li>\u4e0d\u4f1a\u5199\u56de\u78c1\u76d8<\/li>\n<li>\u5185\u5b58\u538b\u529b\u4e0b\u53ea\u80fd swap\/zram&#xff0c;\u4e0d\u80fd\u76f4\u63a5\u4e22<\/li>\n<li>\u4f46\u53ef\u4ee5 ASharedMemory_setProt \u6536\u7d27\u6743\u9650&#xff0c;\u6216\u7528 MADV_FREE\/purgeable \u8ba9\u5185\u6838\u53ef\u56de\u6536<\/li>\n<\/ul>\n<hr \/>\n<h2>\u7b2c 6 \u7ae0&#xff1a;\u5c04\u51fb\u6e38\u620f\u6848\u4f8b<\/h2>\n<h3>\u6848\u4f8b 1&#xff1a;\u7528 smaps \u770b\u6e05 LoadFromFile \u7684\u771f\u76f8<\/h3>\n<p>\u505a\u6cd5&#xff1a;\u52a0\u8f7d\u4e00\u4e2a 80MB \u7684\u5730\u56fe bundle&#xff0c;\u7528 \/proc\/self\/smaps \u89c2\u5bdf\u3002<\/p>\n<p><span class=\"token assign-left variable\">PID<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\"><span class=\"token variable\">$(<\/span>adb shell pidof com.xxx.game <span class=\"token operator\">|<\/span> <span class=\"token function\">tr<\/span> <span class=\"token parameter variable\">-d<\/span> <span class=\"token string\">&#039;\\\\r&#039;<\/span><span class=\"token variable\">)<\/span><\/span><br \/>\nadb shell run-as com.xxx.game <span class=\"token string\">&#034;grep -A 12 &#039;base.bundle&#039; \/proc\/<span class=\"token variable\">$PID<\/span>\/smaps&#034;<\/span><\/p>\n<p>LoadFromFile \u4e4b\u540e\u7acb\u523b\u91c7\u6837&#xff1a;<\/p>\n<p>7b2c000000-7b30f00000 r&#8211;p 00000000 fd:03 1234567   &#8230;\/base.bundle<br \/>\nSize:              80128 kB     \u2190 \u2605 \u865a\u62df\u5730\u5740\u8303\u56f4 80MB<br \/>\nRss:                1436 kB     \u2190 \u2605 \u5b9e\u9645\u9a7b\u7559\u53ea\u6709 1.4MB&#xff01;<br \/>\nPss:                1436 kB<br \/>\nShared_Clean:          0 kB<br \/>\nPrivate_Clean:      1436 kB     \u2190 \u5e72\u51c0\u7684\u79c1\u6709\u6587\u4ef6\u9875<br \/>\nPrivate_Dirty:         0 kB<br \/>\nSwap:                  0 kB<\/p>\n<p>Size 80MB&#xff0c;Rss \u53ea\u6709 1.4MB\u3002 \u8fd9 1.4MB \u662f Unity \u8bfb\u7684\u5143\u6570\u636e&#xff08;AssetBundle \u5934\u3001\u5bf9\u8c61\u7d22\u5f15\u8868&#xff09;\u3002<\/p>\n<p>\u5b9e\u4f8b\u5316\u4e86\u5730\u56fe Prefab \u4e4b\u540e\u518d\u770b&#xff1a;<\/p>\n<p>Size:              80128 kB<br \/>\nRss:               47280 kB     \u2190 \u2605 \u6da8\u5230 46MB&#xff08;\u7528\u5230\u7684\u90e8\u5206\u88ab fault \u8fdb\u6765\u4e86&#xff09;<br \/>\nPrivate_Clean:     47280 kB<\/p>\n<p>\u5bf9\u6bd4 LoadFromMemory&#xff1a;<\/p>\n<p># \u6ca1\u6709 base.bundle \u7684 VMA&#xff08;\u56e0\u4e3a\u4e0d\u662f\u6620\u5c04&#xff0c;\u662f\u62f7\u8fdb\u5806\u91cc&#xff09;<br \/>\n# \u4f46\u770b Native Heap<br \/>\nadb shell &#034;dumpsys meminfo $PID | grep &#039;Native Heap&#039;&#034;<br \/>\nNative Heap    492580   492100   \u2190 \u6da8\u4e86 80MB&#xff08;bundle \u526f\u672c&#xff09;<br \/>\n# \u52a0\u4e0a File.ReadAllBytes \u90a3 80MB \u5728\u6258\u7ba1\u5806&#xff08;LOH&#xff09;<\/p>\n<p>\u7ed3\u8bba\u4e00\u76ee\u4e86\u7136&#xff1a;<\/p>\n<table>\n<tr>LoadFromFileLoadFromMemory<\/tr>\n<tbody>\n<tr>\n<td>\u865a\u62df\u5730\u5740\u5360\u7528<\/td>\n<td>80 MB<\/td>\n<td>0&#xff08;\u4e0d\u6620\u5c04&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u5b9e\u9645\u7269\u7406\u5185\u5b58<\/td>\n<td>1.4 MB \u2192 46 MB&#xff08;\u6309\u9700&#xff09;<\/td>\n<td>160 MB&#xff08;80\u00d72&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u5185\u5b58\u5f52\u7c7b<\/td>\n<td>file-backed clean&#xff0c;\u53ef\u56de\u6536<\/td>\n<td>anon &#043; LOH&#xff0c;\u4e0d\u53ef\u56de\u6536<\/td>\n<\/tr>\n<tr>\n<td>LMK \u773c\u91cc<\/td>\n<td>\u4fbf\u5b9c<\/td>\n<td>\u6602\u8d35<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u6848\u4f8b 2&#xff1a;Major Fault \u98ce\u66b4\u2014\u2014\u6700\u96be\u67e5\u7684\u6218\u6597\u5361\u987f<\/h3>\n<h4>\u73b0\u8c61<\/h4>\n<p>\u67d0\u5c04\u51fb\u6e38\u620f\u6539\u7528 LoadFromFile \u540e&#xff0c;\u542f\u52a8\u5feb\u4e86\u3001\u5185\u5b58\u4f4e\u4e86&#xff0c;\u4f46\u6218\u6597\u4e2d\u5076\u53d1 40~90ms \u5361\u987f\u3002Unity Profiler \u663e\u793a\u5361\u5728\u4e00\u4e2a\u666e\u901a\u7684 Instantiate \u4e0a&#xff0c;\u770b\u4e0d\u51fa\u539f\u56e0\u3002<\/p>\n<h4>\u4e3a\u4ec0\u4e48 Profiler \u770b\u4e0d\u89c1<\/h4>\n<p>major fault \u53d1\u751f\u65f6&#xff1a;<br \/>\n  \u5185\u6838\u5728\u3010\u4f60\u7684\u7ebf\u7a0b\u4e0a\u4e0b\u6587\u3011\u91cc\u7761\u7720\u7b49 IO<br \/>\n  \u2192 \u4ece Profiler \u89d2\u5ea6&#xff0c;\u5c31\u662f&#034;\u8fd9\u4e2a\u51fd\u6570\u6267\u884c\u4e86\u5f88\u4e45&#034;<br \/>\n  \u2192 \u4f46\u51fd\u6570\u91cc\u6ca1\u6709\u4efb\u4f55\u8017\u65f6\u4ee3\u7801<br \/>\n  \u2192 CPU \u91c7\u6837\u5668&#xff08;simpleperf&#xff09;\u4e5f\u770b\u4e0d\u5230&#xff0c;\u56e0\u4e3a\u7ebf\u7a0b\u5728\u7761\u89c9\u4e0d\u5728\u8dd1<\/p>\n<h4>\u7528 \/proc \u6293\u73b0\u573a<\/h4>\n<p><span class=\"token shebang important\">#!\/bin\/bash<\/span><br \/>\n<span class=\"token assign-left variable\">PID<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\"><span class=\"token variable\">$(<\/span>adb shell pidof com.xxx.game <span class=\"token operator\">|<\/span> <span class=\"token function\">tr<\/span> <span class=\"token parameter variable\">-d<\/span> <span class=\"token string\">&#039;\\\\r&#039;<\/span><span class=\"token variable\">)<\/span><\/span><br \/>\n<span class=\"token assign-left variable\">prev_maj<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token assign-left variable\">prev_min<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><br \/>\n<span class=\"token builtin class-name\">echo<\/span> <span class=\"token string\">&#034;sec,minflt_delta,majflt_delta&#034;<\/span><br \/>\n<span class=\"token keyword\">for<\/span> <span class=\"token for-or-select variable\">i<\/span> <span class=\"token keyword\">in<\/span> <span class=\"token variable\"><span class=\"token variable\">$(<\/span><span class=\"token function\">seq<\/span> <span class=\"token number\">1<\/span> <span class=\"token number\">120<\/span><span class=\"token variable\">)<\/span><\/span><span class=\"token punctuation\">;<\/span> <span class=\"token keyword\">do<\/span><br \/>\n  <span class=\"token assign-left variable\">S<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\"><span class=\"token variable\">$(<\/span>adb shell <span class=\"token function\">cat<\/span> \/proc\/$PID\/stat <span class=\"token operator\">|<\/span> <span class=\"token function\">tr<\/span> <span class=\"token parameter variable\">-d<\/span> <span class=\"token string\">&#039;\\\\r&#039;<\/span><span class=\"token variable\">)<\/span><\/span><br \/>\n  <span class=\"token assign-left variable\">MIN<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\"><span class=\"token variable\">$(<\/span><span class=\"token builtin class-name\">echo<\/span> $S <span class=\"token operator\">|<\/span> <span class=\"token function\">awk<\/span> <span class=\"token string\">&#039;{print $10}&#039;<\/span><span class=\"token variable\">)<\/span><\/span><br \/>\n  <span class=\"token assign-left variable\">MAJ<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\"><span class=\"token variable\">$(<\/span><span class=\"token builtin class-name\">echo<\/span> $S <span class=\"token operator\">|<\/span> <span class=\"token function\">awk<\/span> <span class=\"token string\">&#039;{print $12}&#039;<\/span><span class=\"token variable\">)<\/span><\/span><br \/>\n  <span class=\"token builtin class-name\">echo<\/span> <span class=\"token string\">&#034;<span class=\"token variable\">$i<\/span>,<span class=\"token variable\"><span class=\"token variable\">$((<\/span>MIN<span class=\"token operator\">&#8211;<\/span>prev_min<span class=\"token variable\">))<\/span><\/span>,<span class=\"token variable\"><span class=\"token variable\">$((<\/span>MAJ<span class=\"token operator\">&#8211;<\/span>prev_maj<span class=\"token variable\">))<\/span><\/span>&#034;<\/span><br \/>\n  <span class=\"token assign-left variable\">prev_min<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\">$MIN<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token assign-left variable\">prev_maj<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\">$MAJ<\/span><br \/>\n  <span class=\"token function\">sleep<\/span> <span class=\"token number\">1<\/span><br \/>\n<span class=\"token keyword\">done<\/span><\/p>\n<p>\u8f93\u51fa&#xff1a;<\/p>\n<p>sec  minflt_delta  majflt_delta   \u73b0\u573a<br \/>\n5    412           3              \u5f85\u673a<br \/>\n30   1820          18             \u8df3\u4f1e<br \/>\n78   6240          2104           \u2605 \u654c\u4eba\u8fdb\u89c6\u91ce&#xff0c;\u52a0\u8f7d\u76ae\u80a4&#043;\u6b66\u5668<br \/>\n79   3180          1876           \u2605 \u7ee7\u7eed<br \/>\n80   890           142<\/p>\n<p>2104 \u6b21 major fault \u00d7 ~150\u03bcs \u2248 315ms \u7684\u78c1\u76d8\u7b49\u5f85&#xff0c;\u5206\u6563\u5728\u51e0\u5e27\u91cc \u2192 \u5c31\u662f\u90a3\u4e2a 90ms \u5361\u987f\u3002<\/p>\n<h4>\u7cbe\u786e\u5b9a\u4f4d&#xff1a;mincore<\/h4>\n<p>\u60f3\u77e5\u9053&#034;\u5177\u4f53\u54ea\u4e9b\u9875\u4e0d\u5728\u5185\u5b58&#034;&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u67e5\u8be2\u4e00\u6bb5\u6620\u5c04\u6709\u54ea\u4e9b\u9875\u5df2\u9a7b\u7559<\/span><br \/>\n<span class=\"token keyword\">int<\/span> <span class=\"token function\">check_residency<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> addr<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span><span class=\"token operator\">*<\/span> resident<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">int<\/span><span class=\"token operator\">*<\/span> total<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> pages <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span>len <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">4095<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">\/<\/span> <span class=\"token number\">4096<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">char<\/span><span class=\"token operator\">*<\/span> vec <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">malloc<\/span><span class=\"token punctuation\">(<\/span>pages<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">mincore<\/span><span class=\"token punctuation\">(<\/span>addr<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">,<\/span> vec<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">free<\/span><span class=\"token punctuation\">(<\/span>vec<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">int<\/span> r <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">size_t<\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;<\/span> pages<span class=\"token punctuation\">;<\/span> i<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>vec<span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&amp;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span> r<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">;<\/span>      <span class=\"token comment\">\/\/ bit0 &#061; \u5df2\u5728\u5185\u5b58<\/span><\/p>\n<p>    <span class=\"token operator\">*<\/span>resident <span class=\"token operator\">&#061;<\/span> r<span class=\"token punctuation\">;<\/span> <span class=\"token operator\">*<\/span>total <span class=\"token operator\">&#061;<\/span> pages<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">free<\/span><span class=\"token punctuation\">(<\/span>vec<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u52a0\u8f7d\u524d\u540e\u6253\u70b9<\/span><br \/>\nDebug<span class=\"token punctuation\">.<\/span><span class=\"token function\">Log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token interpolation-string\"><span class=\"token string\">$&#034;[MMAP] <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span><span class=\"token expression language-csharp\">bundleName<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span><span class=\"token expression language-csharp\">resident<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">\/<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span><span class=\"token expression language-csharp\">total<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> pages resident &#034;<\/span><\/span> <span class=\"token operator\">&#043;<\/span><br \/>\n          <span class=\"token interpolation-string\"><span class=\"token string\">$&#034;(<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span><span class=\"token expression language-csharp\">resident <span class=\"token operator\">*<\/span> <span class=\"token number\">100<\/span> <span class=\"token operator\">\/<\/span> total<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">%)&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token comment\">\/\/ [MMAP] skin_yuki.bundle: 12\/512 pages resident (2%)   \u2190 \u51e0\u4e4e\u5168\u8981 fault<\/span><\/p>\n<h4>\u4fee\u590d&#xff1a;\u5206\u7ea7\u9884\u70ed<\/h4>\n<p>\u6838\u5fc3\u601d\u8def&#xff1a;\u628a\u4e0d\u53ef\u9884\u6d4b\u7684 fault \u6210\u672c&#xff0c;\u632a\u5230\u73a9\u5bb6\u80fd\u63a5\u53d7\u7684\u65f6\u523b\u3002<\/p>\n<p><span class=\"token comment\">\/\/ Plugins\/Android\/src\/prefetch.c<\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;sys\/mman.h&gt;<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;fcntl.h&gt;<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;unistd.h&gt;<\/span><\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u6e29\u548c\u65b9\u5f0f&#xff1a;\u8ba9\u5185\u6838\u540e\u53f0\u9884\u8bfb&#xff0c;\u4e0d\u963b\u585e<\/span><br \/>\n<span class=\"token keyword\">int<\/span> <span class=\"token function\">warm_hint<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">const<\/span> <span class=\"token keyword\">char<\/span><span class=\"token operator\">*<\/span> path<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">off_t<\/span> off<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> fd <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> O_RDONLY<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>fd <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">posix_fadvise<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">,<\/span> off<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">,<\/span> POSIX_FADV_WILLNEED<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u5185\u6838\u5f02\u6b65\u9884\u8bfb<\/span><br \/>\n    <span class=\"token function\">close<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5f3a\u529b\u65b9\u5f0f&#xff1a;\u6620\u5c04\u540e\u4e3b\u52a8 touch&#xff0c;\u4fdd\u8bc1\u4e00\u5b9a\u8fdb page cache<\/span><br \/>\n<span class=\"token keyword\">int<\/span> <span class=\"token function\">warm_force<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">const<\/span> <span class=\"token keyword\">char<\/span><span class=\"token operator\">*<\/span> path<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">off_t<\/span> off<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">size_t<\/span> len<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> fd <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> O_RDONLY<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>fd <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">off_t<\/span> aligned <span class=\"token operator\">&#061;<\/span> off <span class=\"token operator\">&amp;<\/span> <span class=\"token operator\">~<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">off_t<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">sysconf<\/span><span class=\"token punctuation\">(<\/span>_SC_PAGESIZE<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> delta  <span class=\"token operator\">&#061;<\/span> off <span class=\"token operator\">&#8211;<\/span> aligned<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> p <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> len <span class=\"token operator\">&#043;<\/span> delta<span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token punctuation\">,<\/span> MAP_PRIVATE<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> aligned<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>p <span class=\"token operator\">&#061;&#061;<\/span> MAP_FAILED<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">close<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token function\">madvise<\/span><span class=\"token punctuation\">(<\/span>p<span class=\"token punctuation\">,<\/span> len <span class=\"token operator\">&#043;<\/span> delta<span class=\"token punctuation\">,<\/span> MADV_WILLNEED<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u2605 \u6bcf\u9875\u8bfb\u4e00\u5b57\u8282&#xff0c;\u5f3a\u5236 fault \u8fdb\u6765<\/span><br \/>\n    <span class=\"token keyword\">volatile<\/span> <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">char<\/span> sink <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">size_t<\/span> ps <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">sysconf<\/span><span class=\"token punctuation\">(<\/span>_SC_PAGESIZE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">size_t<\/span> i <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&lt;<\/span> len <span class=\"token operator\">&#043;<\/span> delta<span class=\"token punctuation\">;<\/span> i <span class=\"token operator\">&#043;&#061;<\/span> ps<span class=\"token punctuation\">)<\/span><br \/>\n        sink <span class=\"token operator\">^&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">volatile<\/span> <span class=\"token keyword\">unsigned<\/span> <span class=\"token keyword\">char<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span>p<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span>i<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token function\">munmap<\/span><span class=\"token punctuation\">(<\/span>p<span class=\"token punctuation\">,<\/span> len <span class=\"token operator\">&#043;<\/span> delta<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u2605 \u89e3\u9664\u6620\u5c04&#xff0c;\u4f46 page cache \u91cc\u7684\u9875\u7559\u7740&#xff01;<\/span><br \/>\n    <span class=\"token function\">close<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u5173\u952e\u70b9&#xff1a;munmap \u4e4b\u540e page cache \u91cc\u7684\u9875\u4e0d\u4f1a\u6d88\u5931\u3002 \u6211\u4eec\u53ea\u662f\u501f\u8fd9\u4e2a\u6620\u5c04\u53bb&#034;\u6572\u9192&#034;\u90a3\u4e9b\u9875\u3002<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">BundleWarmup<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token punctuation\">[<\/span><span class=\"token attribute\"><span class=\"token class-name\">DllImport<\/span><span class=\"token attribute-arguments\"><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;prefetch&#034;<\/span><span class=\"token punctuation\">)<\/span><\/span><\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">extern<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">int<\/span><\/span> <span class=\"token function\">warm_hint<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> p<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">long<\/span><\/span> off<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">ulong<\/span><\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">[<\/span><span class=\"token attribute\"><span class=\"token class-name\">DllImport<\/span><span class=\"token attribute-arguments\"><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;prefetch&#034;<\/span><span class=\"token punctuation\">)<\/span><\/span><\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">extern<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">int<\/span><\/span> <span class=\"token function\">warm_force<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> p<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">long<\/span><\/span> off<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">ulong<\/span><\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u2605 \u5f00\u5c40\u524d&#xff0c;\u5728\u540e\u53f0\u7ebf\u7a0b\u9884\u70ed\u672c\u5c40\u5fc5\u9700\u8d44\u6e90<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token return-type class-name\">Task<\/span> <span class=\"token function\">WarmupForMatch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">MatchInfo<\/span> m<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5206\u7ea7&#xff1a;\u6838\u5fc3\u8d44\u6e90\u5f3a\u529b\u9884\u70ed&#xff0c;\u6b21\u8981\u8d44\u6e90\u53ea\u7ed9\u63d0\u793a<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> critical <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ResolveCritical<\/span><span class=\"token punctuation\">(<\/span>m<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u672c\u5c40\u5730\u56fe\u300110 \u4eba\u76ae\u80a4\u3001\u5e38\u7528\u6b66\u5668<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> optional <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ResolveOptional<\/span><span class=\"token punctuation\">(<\/span>m<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u8f7d\u5177\u3001\u7a00\u6709\u6b66\u5668<\/span><\/p>\n<p>        <span class=\"token keyword\">await<\/span> Task<span class=\"token punctuation\">.<\/span><span class=\"token function\">Run<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">foreach<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> b <span class=\"token keyword\">in<\/span> critical<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> e <span class=\"token operator\">&#061;<\/span> packIndex<span class=\"token punctuation\">[<\/span>b<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token function\">warm_force<\/span><span class=\"token punctuation\">(<\/span>packPath<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">long<\/span><span class=\"token punctuation\">)<\/span>e<span class=\"token punctuation\">.<\/span>offset<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">.<\/span>length<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token keyword\">foreach<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> b <span class=\"token keyword\">in<\/span> optional<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> e <span class=\"token operator\">&#061;<\/span> packIndex<span class=\"token punctuation\">[<\/span>b<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n                <span class=\"token function\">warm_hint<\/span><span class=\"token punctuation\">(<\/span>packPath<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">long<\/span><span class=\"token punctuation\">)<\/span>e<span class=\"token punctuation\">.<\/span>offset<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">.<\/span>length<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u4e0d\u963b\u585e<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u9884\u70ed\u5b8c\u6210\u540e\u518d LoadFromFile \u2014\u2014 \u6b64\u65f6\u51e0\u4e4e\u5168\u662f minor fault<\/span><br \/>\n        <span class=\"token keyword\">foreach<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> b <span class=\"token keyword\">in<\/span> critical<span class=\"token punctuation\">)<\/span><br \/>\n            loaded<span class=\"token punctuation\">[<\/span>b<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> AssetBundle<span class=\"token punctuation\">.<\/span><span class=\"token function\">LoadFromFile<\/span><span class=\"token punctuation\">(<\/span>packPath<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> packIndex<span class=\"token punctuation\">[<\/span>b<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>offset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u6548\u679c<\/h4>\n<table>\n<tr>\u6307\u6807\u4fee\u590d\u524d\u4fee\u590d\u540e<\/tr>\n<tbody>\n<tr>\n<td>\u52a0\u8f7d\u754c\u9762\u65f6\u957f<\/td>\n<td>1.2 s<\/td>\n<td>3.6 s<\/td>\n<\/tr>\n<tr>\n<td>\u6218\u6597\u4e2d majflt \u5cf0\u503c<\/td>\n<td>2104 \/s<\/td>\n<td>&lt; 60 \/s<\/td>\n<\/tr>\n<tr>\n<td>\u5e27\u65f6\u95f4 P99<\/td>\n<td>47 ms<\/td>\n<td>11 ms<\/td>\n<\/tr>\n<tr>\n<td>\u5cf0\u503c PSS<\/td>\n<td>720 MB<\/td>\n<td>780 MB<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u4ee3\u4ef7\u662f\u52a0\u8f7d\u6162\u4e86 2.4 \u79d2\u3001\u5185\u5b58\u591a 60MB&#xff0c;\u6362\u6765\u6218\u6597\u5168\u7a0b\u7a33\u5b9a\u3002 \u5bf9\u5c04\u51fb\u6e38\u620f\u8fd9\u7b14\u4ea4\u6613\u975e\u5e38\u5212\u7b97\u3002<\/p>\n<p>&#x1f4cc; \u672c\u6848\u4f8b\u7684\u6838\u5fc3\u6559\u8bad&#xff1a;<br \/>\nmmap \u6ca1\u6709\u6d88\u9664\u6210\u672c&#xff0c;\u5b83\u628a&#034;\u4e00\u6b21\u96c6\u4e2d\u7684\u5927\u62f7\u8d1d&#034;\u6362\u6210\u4e86&#034;\u5206\u6563\u7684\u3001\u4e0d\u53ef\u9884\u6d4b\u7684 page fault&#034;\u3002<br \/>\n\u4f18\u5316\u7684\u672c\u8d28\u662f\u63a7\u5236\u6210\u672c\u53d1\u751f\u7684\u65f6\u673a&#xff0c;\u4e0d\u662f\u6d88\u9664\u6210\u672c\u3002<\/p>\n<hr \/>\n<h3>\u6848\u4f8b 3&#xff1a;mmap \u73af\u5f62\u7f13\u51b2\u2014\u2014\u4e3a\u4ec0\u4e48 SIGKILL \u4e5f\u4e0d\u4e22\u6570\u636e<\/h3>\n<h4>\u9700\u6c42<\/h4>\n<p>Android LMK \u6740\u8fdb\u7a0b\u7528 SIGKILL&#xff0c;\u6ca1\u6709\u4efb\u4f55\u56de\u8c03\u2014\u2014finally\u3001OnApplicationQuit\u3001onDestroy \u5168\u90e8\u4e0d\u6267\u884c\u3002\u4f46\u6211\u4eec\u9700\u8981\u5d29\u6e83\u524d\u7684\u6700\u540e\u51e0\u5343\u6761\u4e8b\u4ef6\u6765\u5b9a\u4f4d\u95ee\u9898\u3002<\/p>\n<h4>\u4e3a\u4ec0\u4e48\u666e\u901a\u5199\u5165\u4f1a\u4e22<\/h4>\n<p>\u4f60\u7684 byte[]<br \/>\n   \u2193 FileStream.Write<br \/>\nFileStream \u5185\u90e8\u7f13\u51b2&#xff08;\u7528\u6237\u6001&#xff01;&#xff09;      \u2190 \u2605 SIGKILL \u65f6\u8fd9\u91cc\u7684\u6570\u636e\u76f4\u63a5\u84b8\u53d1<br \/>\n   \u2193 write() \u7cfb\u7edf\u8c03\u7528<br \/>\n\u5185\u6838 page cache<br \/>\n   \u2193 writeback<br \/>\n\u78c1\u76d8<\/p>\n<h4>\u4e3a\u4ec0\u4e48 mmap \u4e0d\u4f1a\u4e22<\/h4>\n<p>\u4f60\u5199\u5165 mmap \u533a\u57df<br \/>\n   &#061; \u76f4\u63a5\u5199\u7269\u7406\u5185\u5b58<br \/>\n   &#061; \u8fd9\u5757\u7269\u7406\u5185\u5b58\u3010\u5c31\u662f\u3011page cache \u7684\u9875<br \/>\n   \u2193 PTE dirty \u4f4d\u7f6e 1&#xff0c;\u5185\u6838\u6807\u8bb0 PageDirty<br \/>\n   \u2193 \u8fdb\u7a0b\u88ab SIGKILL&#xff1a;\u8fdb\u7a0b\u6b7b\u4e86&#xff0c;\u4f46 page cache \u9875\u5f52\u5185\u6838\u7ba1<br \/>\n   \u2193 writeback \u5185\u6838\u7ebf\u7a0b\u7167\u5e38\u628a\u810f\u9875\u5199\u56de\u6587\u4ef6<br \/>\n\u78c1\u76d8  \u2705 \u6570\u636e\u5728<\/p>\n<p>\u552f\u4e00\u4f1a\u4e22\u7684\u60c5\u51b5&#xff1a;\u5185\u6838\u5d29\u6e83 \/ \u65ad\u7535 \/ \u5f3a\u5236\u62d4\u7535\u6c60\u3002\u8fd9\u4e2a\u6982\u7387\u6bd4 LMK \u6740\u8fdb\u7a0b\u4f4e\u51e0\u4e2a\u6570\u91cf\u7ea7\u3002<\/p>\n<h4>\u5b9e\u73b0<\/h4>\n<p><span class=\"token comment\">\/\/ mmap_ring.c<\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;sys\/mman.h&gt;<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;fcntl.h&gt;<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;unistd.h&gt;<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;stdatomic.h&gt;<\/span><\/span><br \/>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#<\/span><span class=\"token directive keyword\">include<\/span> <span class=\"token string\">&lt;string.h&gt;<\/span><\/span><\/p>\n<p><span class=\"token keyword\">typedef<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">uint32_t<\/span> magic<span class=\"token punctuation\">,<\/span> version<span class=\"token punctuation\">,<\/span> capacity<span class=\"token punctuation\">,<\/span> _pad<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">_Atomic<\/span> <span class=\"token class-name\">uint64_t<\/span> cursor<span class=\"token punctuation\">;<\/span>     <span class=\"token comment\">\/\/ \u5355\u8c03\u9012\u589e&#xff0c;\u4e0d\u56de\u7ed5<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> RingHdr<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">static<\/span> <span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span>    g_base <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">static<\/span> <span class=\"token class-name\">size_t<\/span>   g_size <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">static<\/span> RingHdr<span class=\"token operator\">*<\/span> g_hdr  <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">static<\/span> <span class=\"token class-name\">uint8_t<\/span><span class=\"token operator\">*<\/span> g_data <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">int<\/span> <span class=\"token function\">ring_open<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">const<\/span> <span class=\"token keyword\">char<\/span><span class=\"token operator\">*<\/span> path<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">uint32_t<\/span> cap<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">int<\/span> fd <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> O_RDWR <span class=\"token operator\">|<\/span> O_CREAT<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0600<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>fd <span class=\"token operator\">&lt;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    g_size <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">sizeof<\/span><span class=\"token punctuation\">(<\/span>RingHdr<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> cap<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u2605\u2605 \u5fc5\u987b\u5148 ftruncate&#xff01;<\/span><br \/>\n    <span class=\"token comment\">\/\/    mmap \u8d85\u51fa\u6587\u4ef6\u672b\u5c3e\u7684\u533a\u57df&#xff0c;\u8bbf\u95ee\u65f6\u662f SIGBUS \u800c\u4e0d\u662f\u81ea\u52a8\u6269\u5c55<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token function\">ftruncate<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">,<\/span> g_size<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">close<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u2605\u2605 MAP_SHARED \u2014\u2014 MAP_PRIVATE \u4f1a COW&#xff0c;\u6c38\u8fdc\u5199\u4e0d\u8fdb\u6587\u4ef6<\/span><br \/>\n    g_base <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> g_size<span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token operator\">|<\/span>PROT_WRITE<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token function\">close<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>              <span class=\"token comment\">\/\/ \u2605 mmap \u5efa\u7acb\u540e fd \u53ef\u5173&#xff0c;\u6620\u5c04\u72ec\u7acb\u6301\u6709 inode \u5f15\u7528<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>g_base <span class=\"token operator\">&#061;&#061;<\/span> MAP_FAILED<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">3<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    g_hdr  <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span>RingHdr<span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span>g_base<span class=\"token punctuation\">;<\/span><br \/>\n    g_data <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">uint8_t<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span>g_base <span class=\"token operator\">&#043;<\/span> <span class=\"token keyword\">sizeof<\/span><span class=\"token punctuation\">(<\/span>RingHdr<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>g_hdr<span class=\"token operator\">-&gt;<\/span>magic <span class=\"token operator\">!&#061;<\/span> <span class=\"token number\">0x474E4952<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>          <span class=\"token comment\">\/\/ &#034;RING&#034;<\/span><br \/>\n        g_hdr<span class=\"token operator\">-&gt;<\/span>magic <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0x474E4952<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        g_hdr<span class=\"token operator\">-&gt;<\/span>version <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        g_hdr<span class=\"token operator\">-&gt;<\/span>capacity <span class=\"token operator\">&#061;<\/span> cap<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">atomic_store<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>g_hdr<span class=\"token operator\">-&gt;<\/span>cursor<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u2605 \u5199\u5165&#xff1a;\u7eaf\u5185\u5b58\u64cd\u4f5c&#xff0c;\u96f6\u7cfb\u7edf\u8c03\u7528&#xff0c;\u7ea6 20 ns<\/span><br \/>\n<span class=\"token keyword\">void<\/span> <span class=\"token function\">ring_write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">const<\/span> <span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> src<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">uint32_t<\/span> len<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>g_data <span class=\"token operator\">||<\/span> <span class=\"token operator\">!<\/span>len <span class=\"token operator\">||<\/span> len <span class=\"token operator\">&gt;<\/span> g_hdr<span class=\"token operator\">-&gt;<\/span>capacity<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token class-name\">uint64_t<\/span> pos <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">atomic_fetch_add_explicit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>g_hdr<span class=\"token operator\">-&gt;<\/span>cursor<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">,<\/span><br \/>\n                                             memory_order_relaxed<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">uint32_t<\/span> off <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\">uint32_t<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>pos <span class=\"token operator\">%<\/span> g_hdr<span class=\"token operator\">-&gt;<\/span>capacity<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>off <span class=\"token operator\">&#043;<\/span> len <span class=\"token operator\">&lt;&#061;<\/span> g_hdr<span class=\"token operator\">-&gt;<\/span>capacity<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">memcpy<\/span><span class=\"token punctuation\">(<\/span>g_data <span class=\"token operator\">&#043;<\/span> off<span class=\"token punctuation\">,<\/span> src<span class=\"token punctuation\">,<\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">uint32_t<\/span> first <span class=\"token operator\">&#061;<\/span> g_hdr<span class=\"token operator\">-&gt;<\/span>capacity <span class=\"token operator\">&#8211;<\/span> off<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">memcpy<\/span><span class=\"token punctuation\">(<\/span>g_data <span class=\"token operator\">&#043;<\/span> off<span class=\"token punctuation\">,<\/span> src<span class=\"token punctuation\">,<\/span> first<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">memcpy<\/span><span class=\"token punctuation\">(<\/span>g_data<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">const<\/span> <span class=\"token class-name\">uint8_t<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span>src <span class=\"token operator\">&#043;<\/span> first<span class=\"token punctuation\">,<\/span> len <span class=\"token operator\">&#8211;<\/span> first<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5173\u952e\u8282\u70b9\u4e3b\u52a8\u50ac\u4e00\u4e0b\u5199\u56de&#xff08;\u5f02\u6b65&#xff0c;\u4e0d\u963b\u585e&#xff09;<\/span><br \/>\n<span class=\"token keyword\">void<\/span> <span class=\"token function\">ring_flush<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">void<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>g_base<span class=\"token punctuation\">)<\/span> <span class=\"token function\">msync<\/span><span class=\"token punctuation\">(<\/span>g_base<span class=\"token punctuation\">,<\/span> g_size<span class=\"token punctuation\">,<\/span> MS_ASYNC<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<h4>C# \u4fa7&#xff1a;\u96f6\u5206\u914d\u9762\u5305\u5c51<\/h4>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">Crumb<\/span> <span class=\"token punctuation\">:<\/span> <span class=\"token type-list\"><span class=\"token keyword\">byte<\/span><\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    MapLoadBegin <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> MapLoadEnd<span class=\"token punctuation\">,<\/span> PlayerSpawn<span class=\"token punctuation\">,<\/span> WeaponSwitch<span class=\"token punctuation\">,<\/span><br \/>\n    BundleLoad<span class=\"token punctuation\">,<\/span> VfxSpawn<span class=\"token punctuation\">,<\/span> MemPressure<span class=\"token punctuation\">,<\/span> NetReconnect<span class=\"token punctuation\">,<\/span> MajorFaultBurst<span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">Breadcrumb<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token punctuation\">[<\/span><span class=\"token attribute\"><span class=\"token class-name\">DllImport<\/span><span class=\"token attribute-arguments\"><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;mmap_ring&#034;<\/span><span class=\"token punctuation\">)<\/span><\/span><\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">extern<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">int<\/span><\/span>  <span class=\"token function\">ring_open<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> p<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">uint<\/span><\/span> cap<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">[<\/span><span class=\"token attribute\"><span class=\"token class-name\">DllImport<\/span><span class=\"token attribute-arguments\"><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;mmap_ring&#034;<\/span><span class=\"token punctuation\">)<\/span><\/span><\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">extern<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">ring_write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">IntPtr<\/span> src<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">uint<\/span><\/span> len<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">[<\/span><span class=\"token attribute\"><span class=\"token class-name\">DllImport<\/span><span class=\"token attribute-arguments\"><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;mmap_ring&#034;<\/span><span class=\"token punctuation\">)<\/span><\/span><\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">extern<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">ring_flush<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">Init<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u2605 \u5fc5\u987b\u653e\u5185\u90e8\u5b58\u50a8&#xff0c;\u5916\u90e8\u5b58\u50a8\u8d70 FUSE&#xff0c;mmap \u6027\u80fd\u5dee<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> p <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">.<\/span><span class=\"token function\">Combine<\/span><span class=\"token punctuation\">(<\/span>Application<span class=\"token punctuation\">.<\/span>persistentDataPath<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;logs\/crumb.ring&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        Directory<span class=\"token punctuation\">.<\/span><span class=\"token function\">CreateDirectory<\/span><span class=\"token punctuation\">(<\/span>Path<span class=\"token punctuation\">.<\/span><span class=\"token function\">GetDirectoryName<\/span><span class=\"token punctuation\">(<\/span>p<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">ring_open<\/span><span class=\"token punctuation\">(<\/span>p<span class=\"token punctuation\">,<\/span> <span class=\"token number\">256<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">1024<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>    <span class=\"token comment\">\/\/ 256KB \u2248 65536 \u6761<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token keyword\">unsafe<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">Mark<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\">Crumb<\/span> id<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">ushort<\/span><\/span> param<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">byte<\/span><span class=\"token operator\">*<\/span> b <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">stackalloc<\/span> <span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">4<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span>        <span class=\"token comment\">\/\/ \u6808\u4e0a&#xff0c;\u96f6 GC<\/span><br \/>\n        b<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">)<\/span>id<span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token operator\">*<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">ushort<\/span><span class=\"token operator\">*<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>b <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> param<span class=\"token punctuation\">;<\/span><br \/>\n        b<span class=\"token punctuation\">[<\/span><span class=\"token number\">3<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">byte<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">(<\/span>Time<span class=\"token punctuation\">.<\/span>frameCount <span class=\"token operator\">&amp;<\/span> <span class=\"token number\">0xFF<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">ring_write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>IntPtr<span class=\"token punctuation\">)<\/span>b<span class=\"token punctuation\">,<\/span> <span class=\"token number\">4<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u6b7b\u4ea1\u3001\u56de\u5408\u7ed3\u675f\u7b49\u5173\u952e\u70b9&#xff0c;\u50ac\u4e00\u6b21\u5199\u56de<\/span><br \/>\n    <span class=\"token keyword\">public<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">Checkpoint<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token function\">ring_flush<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u5d29\u6e83\u540e\u8bfb\u53d6<\/h4>\n<p><span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">Start<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> flag <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">.<\/span><span class=\"token function\">Combine<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">NoBackupDir<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;crash_flag&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>File<span class=\"token punctuation\">.<\/span><span class=\"token function\">Exists<\/span><span class=\"token punctuation\">(<\/span>flag<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u2605 \u4e0a\u6b21\u5f02\u5e38\u9000\u51fa&#xff0c;\u4f46\u5185\u6838\u4fdd\u4f4f\u4e86 mmap \u7684\u810f\u9875<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> crumbs <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ParseRing<\/span><span class=\"token punctuation\">(<\/span>ringPath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token function\">UploadCrashContext<\/span><span class=\"token punctuation\">(<\/span>crumbs<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ &#034;\u6b7b\u4e4b\u524d\u6700\u540e 65536 \u4e2a\u4e8b\u4ef6&#034;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    File<span class=\"token punctuation\">.<\/span><span class=\"token function\">WriteAllText<\/span><span class=\"token punctuation\">(<\/span>flag<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">OnApplicationQuit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> File<span class=\"token punctuation\">.<\/span><span class=\"token function\">Delete<\/span><span class=\"token punctuation\">(<\/span><span class=\"token range operator\">..<\/span><span class=\"token punctuation\">.<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u6b63\u5e38\u9000\u51fa\u624d\u5220<\/span><\/p>\n<h4>\u4e09\u79cd\u5199\u5165\u65b9\u5f0f\u5b9e\u6d4b<\/h4>\n<table>\n<tr>\u65b9\u5f0f\u5355\u6b21\u8017\u65f6SIGKILL \u540e\u7cfb\u7edf\u8c03\u7528<\/tr>\n<tbody>\n<tr>\n<td>FileStream.Write<\/td>\n<td>~800 ns<\/td>\n<td>\u274c \u4e22\u5931<\/td>\n<td>\u7f13\u51b2\u6ee1\u65f6<\/td>\n<\/tr>\n<tr>\n<td>Write &#043; Flush(true)<\/td>\n<td>~2 ms<\/td>\n<td>\u2705 \u4fdd\u7559<\/td>\n<td>\u6bcf\u6b21 fsync<\/td>\n<\/tr>\n<tr>\n<td>mmap \u5199\u5165<\/td>\n<td>~20 ns<\/td>\n<td>\u2705 \u4fdd\u7559<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>mmap \u662f\u552f\u4e00\u540c\u65f6\u505a\u5230&#034;\u5feb&#034;\u548c&#034;\u53ef\u9760&#034;\u7684\u65b9\u6848&#xff0c;\u800c\u8fd9\u5b8c\u5168\u5f52\u529f\u4e8e&#034;\u7528\u6237\u5730\u5740\u76f4\u63a5\u6307\u5411 page cache&#034;\u3002<\/p>\n<hr \/>\n<h3>\u6848\u4f8b 4&#xff1a;LMK \u89c6\u89d2\u2014\u2014mmap \u8ba9\u4f60\u66f4\u96be\u88ab\u6740<\/h3>\n<h4>\u539f\u7406<\/h4>\n<p>Android LMK \u8ba1\u7b97\u6740\u8c01\u65f6&#xff0c;\u770b\u7684\u662f&#034;\u6740\u4e86\u4f60\u80fd\u91ca\u653e\u591a\u5c11&#034;\u3002\u800c\u4e0d\u540c\u7c7b\u578b\u7684\u5185\u5b58&#034;\u91ca\u653e\u6210\u672c&#034;\u5b8c\u5168\u4e0d\u540c&#xff1a;<\/p>\n<p>\u4f60\u7684 1GB \u5185\u5b58\u6784\u6210 A&#xff08;LoadFromMemory \u8def\u7ebf&#xff09;&#xff1a;<br \/>\n  \u251c\u2500 400 MB Native Heap&#xff08;\u533f\u540d\u9875&#xff09;\u2192 \u5fc5\u987b\u6740\u8fdb\u7a0b\u624d\u80fd\u91ca\u653e<br \/>\n  \u251c\u2500 300 MB \u6258\u7ba1\u5806&#xff08;\u533f\u540d\u9875&#xff09;     \u2192 \u5fc5\u987b\u6740\u8fdb\u7a0b<br \/>\n  \u2514\u2500 300 MB \u663e\u5b58<\/p>\n<p>\u4f60\u7684 1GB \u5185\u5b58\u6784\u6210 B&#xff08;LoadFromFile \u8def\u7ebf&#xff09;&#xff1a;<br \/>\n  \u251c\u2500 150 MB Native Heap&#xff08;\u533f\u540d\u9875&#xff09;<br \/>\n  \u251c\u2500 100 MB \u6258\u7ba1\u5806<br \/>\n  \u251c\u2500 450 MB file-backed clean&#xff08;mmap \u7684 bundle&#xff09;<br \/>\n  \u2502      \u2192 \u2605 kswapd \u53ef\u4ee5\u76f4\u63a5\u56de\u6536&#xff0c;\u4e0d\u9700\u8981\u6740\u4f60<br \/>\n  \u2514\u2500 300 MB \u663e\u5b58<\/p>\n<p>\u5728\u5185\u5b58\u538b\u529b\u4e0b&#xff1a;<\/p>\n<ul>\n<li>\u6784\u6210 A&#xff1a;\u7cfb\u7edf\u6ca1\u5f97\u9009&#xff0c;\u53ea\u80fd\u6740\u8fdb\u7a0b<\/li>\n<li>\u6784\u6210 B&#xff1a;\u7cfb\u7edf\u5148\u56de\u6536\u90a3 450MB \u5e72\u51c0\u6587\u4ef6\u9875 \u2192 \u4f60\u6d3b\u4e0b\u6765\u4e86&#xff08;\u4ee3\u4ef7\u662f\u540e\u7eed major fault&#xff09;<\/li>\n<\/ul>\n<h4>\u5b9e\u6d4b\u9a8c\u8bc1<\/h4>\n<p><span class=\"token comment\"># \u5236\u9020\u5185\u5b58\u538b\u529b&#xff1a;\u540e\u53f0\u5f00\u4e00\u5806 App&#xff0c;\u7136\u540e\u89c2\u5bdf<\/span><br \/>\nadb shell <span class=\"token string\">&#034;dumpsys meminfo com.xxx.game | grep -E &#039;.apk mmap|Native Heap|TOTAL&#039;&#034;<\/span><\/p>\n<p>\u6784\u6210 B \u7684\u8f93\u51fa&#xff1a;<\/p>\n<p>Native Heap    152400   151900<br \/>\n.apk mmap      458200        0   458200   \u2190 \u2605 Private Clean \u5168\u90e8\u53ef\u56de\u6536<br \/>\nTOTAL         1010000   580000   430000<\/p>\n<p>\u6ce8\u610f .apk mmap \u90a3\u4e00\u884c Private Dirty &#061; 0&#xff0c;Private Clean &#061; 458200\u3002<\/p>\n<p>Private Clean \u5c31\u662f&#034;\u968f\u65f6\u53ef\u4ee5\u4e22\u7684\u5185\u5b58&#034;\u3002\u5b83\u867d\u7136\u8ba1\u5165 PSS&#xff0c;\u4f46\u5bf9 LMK \u6765\u8bf4\u662f&#034;\u8f6f\u7684&#034;\u3002<\/p>\n<h4>\u538b\u6d4b\u5bf9\u6bd4<\/h4>\n<p>\u540c\u4e00\u53f0 4GB \u673a\u5668&#xff0c;\u540e\u53f0\u5f00 8 \u4e2a App&#xff0c;\u73a9 50 \u5c40&#xff1a;<\/p>\n<table>\n<tr>\u52a0\u8f7d\u65b9\u5f0f\u5e73\u5747 PSS\u88ab LMK \u6740\u6b21\u6570\u6218\u6597\u5361\u987f P99<\/tr>\n<tbody>\n<tr>\n<td>LoadFromMemory<\/td>\n<td>1180 MB<\/td>\n<td>12 \/ 50<\/td>\n<td>9 ms<\/td>\n<\/tr>\n<tr>\n<td>LoadFromFile&#xff08;\u65e0\u9884\u70ed&#xff09;<\/td>\n<td>720 MB<\/td>\n<td>1 \/ 50<\/td>\n<td>47 ms<\/td>\n<\/tr>\n<tr>\n<td>LoadFromFile &#043; \u9884\u70ed<\/td>\n<td>780 MB<\/td>\n<td>0 \/ 50<\/td>\n<td>11 ms<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u7b2c\u4e09\u884c\u662f\u6700\u4f18\u89e3&#xff1a;mmap \u63d0\u4f9b&#034;\u53ef\u56de\u6536&#034;\u7684\u5c5e\u6027\u907f\u514d\u88ab\u6740&#xff0c;\u9884\u70ed\u63d0\u4f9b&#034;\u9875\u5df2\u9a7b\u7559&#034;\u907f\u514d\u5361\u987f\u3002<\/p>\n<hr \/>\n<h3>\u6848\u4f8b 5&#xff1a;\u5927\u6587\u4ef6 Pack &#043; Offset\u2014\u2014\u51cf\u5c11 VMA \u4e0e TLB \u538b\u529b<\/h3>\n<h4>\u95ee\u9898<\/h4>\n<p>LoadFromFile \u6709\u4e2a\u5e26 offset \u7684\u91cd\u8f7d&#xff0c;\u4f46\u5f88\u591a\u4eba\u4e0d\u77e5\u9053\u4e3a\u4ec0\u4e48\u8981\u7528\u5b83&#xff1a;<\/p>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">static<\/span> <span class=\"token return-type class-name\">AssetBundle<\/span> <span class=\"token function\">LoadFromFile<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> path<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">uint<\/span><\/span> crc<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\"><span class=\"token keyword\">ulong<\/span><\/span> offset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<h4>200 \u4e2a\u5c0f\u6587\u4ef6 vs 1 \u4e2a\u5927\u6587\u4ef6<\/h4>\n<p>\u3010200 \u4e2a\u72ec\u7acb bundle\u3011<br \/>\n  \u251c\u2500 200 \u6b21 open\/close \u7cfb\u7edf\u8c03\u7528<br \/>\n  \u251c\u2500 200 \u4e2a VMA \u2192 VMA \u7ea2\u9ed1\u6811\u53d8\u6df1&#xff0c;\u6bcf\u6b21 fault \u67e5\u627e\u53d8\u6162<br \/>\n  \u251c\u2500 \u6587\u4ef6\u7cfb\u7edf\u5143\u6570\u636e&#xff1a;200 \u4e2a inode&#xff0c;\u6bcf\u4e2a\u81f3\u5c11\u5360 1 \u4e2a block<br \/>\n  \u251c\u2500 \u78c1\u76d8\u5e03\u5c40\u5206\u6563 \u2192 \u9884\u8bfb\u51e0\u4e4e\u65e0\u6548&#xff0c;\u5168\u662f\u968f\u673a IO<br \/>\n  \u2514\u2500 Android FUSE \u5c42\u6bcf\u4e2a\u6587\u4ef6\u90fd\u8981\u8f6c\u53d1<\/p>\n<p>\u30101 \u4e2a\u5927 pack &#043; offset\u3011<br \/>\n  \u251c\u2500 1 \u6b21 open<br \/>\n  \u251c\u2500 \u53ef\u4ee5\u53ea\u5efa 1 \u4e2a\u5927 VMA&#xff08;\u5982\u679c\u4e00\u6b21\u6620\u5c04\u6574\u4e2a pack&#xff09;<br \/>\n  \u251c\u2500 \u987a\u5e8f\u5e03\u5c40 \u2192 \u5185\u6838 readahead \u547d\u4e2d\u7387\u9ad8<br \/>\n  \u2514\u2500 fault-around \u80fd\u4e00\u6b21\u6620\u5c04 16 \u9875<\/p>\n<h4>\u5b9e\u73b0<\/h4>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">PackedBundleStore<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u7d22\u5f15&#xff1a;name \u2192 (pageAlignedOffset, length, crc)<\/span><br \/>\n    <span class=\"token class-name\">Dictionary<span class=\"token punctuation\">&lt;<\/span><span class=\"token keyword\">string<\/span><span class=\"token punctuation\">,<\/span> PackEntry<span class=\"token punctuation\">&gt;<\/span><\/span> index<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> packPath<span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">public<\/span> <span class=\"token return-type class-name\">AssetBundle<\/span> <span class=\"token function\">Load<\/span><span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">string<\/span><\/span> name<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> e <span class=\"token operator\">&#061;<\/span> index<span class=\"token punctuation\">[<\/span>name<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u2605 offset \u5fc5\u987b\u9875\u5bf9\u9f50&#xff0c;\u6253\u5305\u5de5\u5177\u8981\u4fdd\u8bc1\u8fd9\u4e00\u70b9<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> AssetBundle<span class=\"token punctuation\">.<\/span><span class=\"token function\">LoadFromFile<\/span><span class=\"token punctuation\">(<\/span>packPath<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">.<\/span>crc<span class=\"token punctuation\">,<\/span> e<span class=\"token punctuation\">.<\/span>offset<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6253\u5305\u5de5\u5177\u7684\u5173\u952e\u7ea6\u675f&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u751f\u6210 pack \u65f6&#xff0c;\u6bcf\u4e2a bundle \u8d77\u59cb\u4f4d\u7f6e\u5bf9\u9f50\u5230 16KB<\/span><br \/>\n<span class=\"token comment\">\/\/ &#xff08;\u517c\u5bb9 Android 15 \u7684 16KB \u9875&#xff1b;4KB \u9875\u673a\u5668\u4e0a\u4e5f\u5b89\u5168&#xff09;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token class-name\"><span class=\"token keyword\">int<\/span><\/span> ALIGN <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">16<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">1024<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">foreach<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> bundle <span class=\"token keyword\">in<\/span> bundles<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\"><span class=\"token keyword\">long<\/span><\/span> pad <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span>ALIGN <span class=\"token operator\">&#8211;<\/span> <span class=\"token punctuation\">(<\/span>writer<span class=\"token punctuation\">.<\/span>Position <span class=\"token operator\">%<\/span> ALIGN<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">%<\/span> ALIGN<span class=\"token punctuation\">;<\/span><br \/>\n    writer<span class=\"token punctuation\">.<\/span><span class=\"token function\">Write<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">new<\/span> <span class=\"token constructor-invocation class-name\"><span class=\"token keyword\">byte<\/span><\/span><span class=\"token punctuation\">[<\/span>pad<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>                 <span class=\"token comment\">\/\/ \u586b\u5145\u5bf9\u9f50<\/span><br \/>\n    index<span class=\"token punctuation\">[<\/span>bundle<span class=\"token punctuation\">.<\/span>Name<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token constructor-invocation class-name\">PackEntry<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        offset <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">ulong<\/span><span class=\"token punctuation\">)<\/span>writer<span class=\"token punctuation\">.<\/span>Position<span class=\"token punctuation\">,<\/span><br \/>\n        length <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">ulong<\/span><span class=\"token punctuation\">)<\/span>bundle<span class=\"token punctuation\">.<\/span>Length<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    writer<span class=\"token punctuation\">.<\/span><span class=\"token function\">Write<\/span><span class=\"token punctuation\">(<\/span>bundle<span class=\"token punctuation\">.<\/span>Data<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u586b\u5145\u6d6a\u8d39&#xff1a;\u5e73\u5747\u6bcf\u4e2a bundle \u6d6a\u8d39 8KB&#xff0c;200 \u4e2a &#061; 1.6MB\u3002\u6362\u6765\u7684\u662f\u52a0\u8f7d\u901f\u5ea6 3 \u500d\u63d0\u5347&#xff0c;\u975e\u5e38\u503c\u3002<\/p>\n<h4>\u5b9e\u6d4b<\/h4>\n<table>\n<tr>\u65b9\u6848\u51b7\u542f\u52a8\u52a0\u8f7d 200 bundleVMA \u6570\u91cfmajflt<\/tr>\n<tbody>\n<tr>\n<td>200 \u4e2a\u72ec\u7acb\u6587\u4ef6<\/td>\n<td>1820 ms<\/td>\n<td>&#043;200<\/td>\n<td>4210<\/td>\n<\/tr>\n<tr>\n<td>1 \u4e2a pack &#043; offset<\/td>\n<td>610 ms<\/td>\n<td>&#043;12<\/td>\n<td>1180<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u6848\u4f8b 6&#xff1a;\u8de8\u8fdb\u7a0b\u5171\u4eab\u2014\u2014\u5f55\u5236\u8fdb\u7a0b<\/h3>\n<p>\u67b6\u6784&#xff1a;\u4e3b\u8fdb\u7a0b\u6e32\u67d3&#xff0c;\u72ec\u7acb\u8fdb\u7a0b\u505a\u7f16\u7801\u63a8\u6d41&#xff0c;\u907f\u514d\u7f16\u7801\u5360\u7528\u4e3b\u8fdb\u7a0b CPU\u3002<\/p>\n<p>\u4e3b\u8fdb\u7a0b                          \u5f55\u5236\u8fdb\u7a0b<br \/>\n  \u251c\u2500 \u6e32\u67d3 \u2192 \u62ff\u5230\u5e27\u6570\u636e             \u251c\u2500 H.264 \u7f16\u7801<br \/>\n  \u251c\u2500 \u97f3\u9891\u6df7\u97f3 \u2192 PCM                \u2514\u2500 \u63a8\u6d41<br \/>\n  \u2514\u2500 \u9700\u8981\u4f20\u7ed9\u5f55\u5236\u8fdb\u7a0b<\/p>\n<p>\u6bcf\u5e27 1080p RGBA &#061; 8 MB<br \/>\n60fps \u2192 480 MB\/s<br \/>\n\u7528 Binder \u4f20 \u2192 \u2605 \u76f4\u63a5\u628a\u5185\u5b58\u5e26\u5bbd\u6253\u6b7b<\/p>\n<h4>\u5171\u4eab\u5185\u5b58\u65b9\u6848<\/h4>\n<p><span class=\"token comment\">\/\/ \u4e3b\u8fdb\u7a0b&#xff1a;\u521b\u5efa<\/span><br \/>\n<span class=\"token keyword\">int<\/span> fd <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ASharedMemory_create<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;frame_ring&#034;<\/span><span class=\"token punctuation\">,<\/span> RING_BYTES<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> base <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> RING_BYTES<span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token operator\">|<\/span>PROT_WRITE<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token comment\">\/\/ \u901a\u8fc7 Binder \u4f20 fd&#xff08;\u53ea\u4f20 fd&#xff0c;\u4e0d\u4f20\u6570\u636e&#xff01;&#xff09;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5f55\u5236\u8fdb\u7a0b&#xff1a;\u6620\u5c04\u540c\u4e00\u6279\u7269\u7406\u9875<\/span><br \/>\n<span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> base2 <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mmap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">NULL<\/span><span class=\"token punctuation\">,<\/span> RING_BYTES<span class=\"token punctuation\">,<\/span> PROT_READ<span class=\"token punctuation\">,<\/span> MAP_SHARED<span class=\"token punctuation\">,<\/span> recv_fd<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u7269\u7406\u5185\u5b58<br \/>\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502  \u533f\u540d\u5171\u4eab\u9875&#xff08;ashmem&#xff09;     \u2502<br \/>\n\u2514\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2518<br \/>\n   \u2502                  \u2502<br \/>\n\u4e3b\u8fdb\u7a0b PTE        \u5f55\u5236\u8fdb\u7a0b PTE<br \/>\n&#xff08;\u865a\u62df\u5730\u5740 A&#xff09;      &#xff08;\u865a\u62df\u5730\u5740 B&#xff09;<\/p>\n<p>\u2605 \u4e24\u4e2a\u4e0d\u540c\u7684\u865a\u62df\u5730\u5740&#xff0c;\u540c\u4e00\u6279\u7269\u7406\u9875<br \/>\n\u2605 \u4e3b\u8fdb\u7a0b\u5199\u5165 \u2192 \u5f55\u5236\u8fdb\u7a0b\u7acb\u523b\u53ef\u89c1&#xff0c;\u96f6\u62f7\u8d1d<\/p>\n<h4>\u65e0\u9501\u73af\u5f62\u961f\u5217<\/h4>\n<p><span class=\"token keyword\">typedef<\/span> <span class=\"token keyword\">struct<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">_Atomic<\/span> <span class=\"token class-name\">uint64_t<\/span> write_pos<span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u53ea\u6709\u751f\u4ea7\u8005\u5199<\/span><br \/>\n    <span class=\"token keyword\">_Atomic<\/span> <span class=\"token class-name\">uint64_t<\/span> read_pos<span class=\"token punctuation\">;<\/span>    <span class=\"token comment\">\/\/ \u53ea\u6709\u6d88\u8d39\u8005\u5199<\/span><br \/>\n    <span class=\"token class-name\">uint32_t<\/span> slots<span class=\"token punctuation\">,<\/span> slot_size<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span> ShmRing<span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u751f\u4ea7\u8005<\/span><br \/>\nbool <span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>ShmRing<span class=\"token operator\">*<\/span> r<span class=\"token punctuation\">,<\/span> <span class=\"token class-name\">uint8_t<\/span><span class=\"token operator\">*<\/span> data<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">const<\/span> <span class=\"token keyword\">void<\/span><span class=\"token operator\">*<\/span> src<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\">uint64_t<\/span> w  <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">atomic_load_explicit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>r<span class=\"token operator\">-&gt;<\/span>write_pos<span class=\"token punctuation\">,<\/span> memory_order_relaxed<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token class-name\">uint64_t<\/span> rd <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">atomic_load_explicit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>r<span class=\"token operator\">-&gt;<\/span>read_pos<span class=\"token punctuation\">,<\/span>  memory_order_acquire<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>w <span class=\"token operator\">&#8211;<\/span> rd <span class=\"token operator\">&gt;&#061;<\/span> r<span class=\"token operator\">-&gt;<\/span>slots<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span> false<span class=\"token punctuation\">;<\/span>              <span class=\"token comment\">\/\/ \u6ee1 \u2192 \u4e22\u5e27<\/span><\/p>\n<p>    <span class=\"token function\">memcpy<\/span><span class=\"token punctuation\">(<\/span>data <span class=\"token operator\">&#043;<\/span> <span class=\"token punctuation\">(<\/span>w <span class=\"token operator\">%<\/span> r<span class=\"token operator\">-&gt;<\/span>slots<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">*<\/span> r<span class=\"token operator\">-&gt;<\/span>slot_size<span class=\"token punctuation\">,<\/span> src<span class=\"token punctuation\">,<\/span> r<span class=\"token operator\">-&gt;<\/span>slot_size<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u2605 release&#xff1a;\u4fdd\u8bc1 memcpy \u5bf9\u6d88\u8d39\u8005\u53ef\u89c1\u540e\u624d\u66f4\u65b0\u6e38\u6807<\/span><br \/>\n    <span class=\"token function\">atomic_store_explicit<\/span><span class=\"token punctuation\">(<\/span><span class=\"token operator\">&amp;<\/span>r<span class=\"token operator\">-&gt;<\/span>write_pos<span class=\"token punctuation\">,<\/span> w <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> memory_order_release<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> true<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>\u4e09\u4e2a\u5fc5\u987b\u77e5\u9053\u7684\u5751<\/h4>\n<p>\u2460 \u7edd\u5bf9\u4e0d\u80fd\u5728\u5171\u4eab\u5185\u5b58\u91cc\u5b58\u6307\u9488<br \/>\n   \u4e24\u4e2a\u8fdb\u7a0b\u7684\u865a\u62df\u5730\u5740\u4e0d\u540c&#xff0c;\u6307\u9488\u6beb\u65e0\u610f\u4e49<br \/>\n   \u2192 \u53ea\u80fd\u5b58\u504f\u79fb\u91cf&#xff08;offset&#xff09;<\/p>\n<p>\u2461 \u4e0d\u80fd\u5b58 C&#043;&#043; \u5bf9\u8c61<br \/>\n   \u6709\u865a\u8868\u6307\u9488 \u2192 \u5c31\u662f\u6307\u9488\u95ee\u9898<\/p>\n<p>\u2462 \u5bf9\u65b9\u8fdb\u7a0b\u5d29\u6e83\u65f6\u72b6\u6001\u672a\u5b9a\u4e49<br \/>\n   \u5f55\u5236\u8fdb\u7a0b\u6302\u4e86 \u2192 \u73af\u5f62\u7f13\u51b2\u4f1a\u586b\u6ee1 \u2192 \u751f\u4ea7\u8005\u5fc5\u987b\u80fd\u4f18\u96c5\u4e22\u5e27<br \/>\n   \u2192 \u9700\u8981\u5fc3\u8df3&#xff1a;\u5728\u5171\u4eab\u5185\u5b58\u91cc\u653e\u4e00\u4e2a heartbeat \u8ba1\u6570\u5668&#xff0c;<br \/>\n     \u6d88\u8d39\u8005\u5b9a\u671f &#043;&#043;&#xff0c;\u751f\u4ea7\u8005\u68c0\u6d4b\u8d85\u65f6\u540e\u505c\u6b62 push<\/p>\n<hr \/>\n<h2>\u7b2c 7 \u7ae0&#xff1a;\u600e\u4e48\u5ea6\u91cf<\/h2>\n<h3>7.1 \u770b\u6620\u5c04\u5168\u8c8c<\/h3>\n<p><span class=\"token assign-left variable\">PID<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token variable\"><span class=\"token variable\">$(<\/span>adb shell pidof com.xxx.game <span class=\"token operator\">|<\/span> <span class=\"token function\">tr<\/span> <span class=\"token parameter variable\">-d<\/span> <span class=\"token string\">&#039;\\\\r&#039;<\/span><span class=\"token variable\">)<\/span><\/span><\/p>\n<p><span class=\"token comment\"># \u6c47\u603b&#xff08;\u6700\u5feb\u770b\u5168\u5c40&#xff09;<\/span><br \/>\nadb shell run-as com.xxx.game <span class=\"token function\">cat<\/span> \/proc\/<span class=\"token variable\">$PID<\/span>\/smaps_rollup<\/p>\n<p>Rss:              742180 kB<br \/>\nPss:              718240 kB<br \/>\nShared_Clean:      58200 kB<br \/>\nPrivate_Clean:    412300 kB    \u2190 \u2605 \u53ef\u76f4\u63a5\u56de\u6536\u7684\u90e8\u5206&#xff0c;\u8d8a\u5927\u8d8a&#034;\u6297\u6740&#034;<br \/>\nPrivate_Dirty:    271680 kB    \u2190 \u2605 \u5fc5\u987b\u6740\u8fdb\u7a0b\u624d\u80fd\u91ca\u653e<br \/>\nSwap:                  0 kB<\/p>\n<p>\u6838\u5fc3\u6307\u6807&#xff1a;Private_Clean \/ Private_Dirty \u7684\u6bd4\u503c\u3002 \u6bd4\u503c\u8d8a\u9ad8&#xff0c;\u4f60\u5728 LMK \u773c\u91cc\u8d8a\u5b89\u5168\u3002<\/p>\n<h3>7.2 \u770b Page Fault<\/h3>\n<p><span class=\"token comment\"># $10 &#061; minflt, $12 &#061; majflt<\/span><br \/>\nadb shell <span class=\"token function\">cat<\/span> \/proc\/<span class=\"token variable\">$PID<\/span>\/stat <span class=\"token operator\">|<\/span> <span class=\"token function\">awk<\/span> <span class=\"token string\">&#039;{print &#034;minflt&#061;&#034;$10, &#034;majflt&#061;&#034;$12}&#039;<\/span><\/p>\n<p>\u5224\u8bfb&#xff1a;<\/p>\n<ul>\n<li>minflt \u5927\u662f\u6b63\u5e38\u7684&#xff08;\u9996\u6b21\u89e6\u78b0\u5df2\u7f13\u5b58\u7684\u9875&#xff09;<\/li>\n<li>majflt \u5728\u6218\u6597\u4e2d\u6301\u7eed\u589e\u957f &#061; \u6709\u95ee\u9898<\/li>\n<\/ul>\n<h3>7.3 \u770b\u5355\u4e2a\u6620\u5c04\u7684\u9a7b\u7559\u7387<\/h3>\n<p>adb shell run-as com.xxx.game <span class=\"token string\">&#034;grep -A 6 &#039;base.pack&#039; \/proc\/<span class=\"token variable\">$PID<\/span>\/smaps&#034;<\/span><\/p>\n<p>Size:             820480 kB<br \/>\nRss:              186240 kB     \u2190 \u9a7b\u7559\u7387 22.7%<\/p>\n<p>\u9a7b\u7559\u7387\u80fd\u544a\u8bc9\u4f60&#034;\u9884\u70ed\u505a\u5f97\u591f\u4e0d\u591f&#034;\u3002<\/p>\n<h3>7.4 \u6e38\u620f\u5185\u5b9e\u65f6\u76d1\u63a7<\/h3>\n<p><span class=\"token keyword\">public<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token class-name\">FaultMonitor<\/span> <span class=\"token punctuation\">:<\/span> <span class=\"token type-list\"><span class=\"token class-name\">MonoBehaviour<\/span><\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token class-name\"><span class=\"token keyword\">long<\/span><\/span> lastMaj<span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token return-type class-name\"><span class=\"token keyword\">void<\/span><\/span> <span class=\"token function\">Update<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>Time<span class=\"token punctuation\">.<\/span>frameCount <span class=\"token operator\">%<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">!&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">long<\/span><\/span> maj <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ReadMajFlt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token class-name\"><span class=\"token keyword\">long<\/span><\/span> delta <span class=\"token operator\">&#061;<\/span> maj <span class=\"token operator\">&#8211;<\/span> lastMaj<span class=\"token punctuation\">;<\/span><br \/>\n        lastMaj <span class=\"token operator\">&#061;<\/span> maj<span class=\"token punctuation\">;<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u2605 \u6218\u6597\u4e2d\u6bcf\u79d2 major fault \u8d85\u8fc7 100 \u2192 \u9884\u70ed\u7b56\u7565\u6709\u6f0f\u6d1e<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>BattleState<span class=\"token punctuation\">.<\/span>InBattle <span class=\"token operator\">&amp;&amp;<\/span> delta <span class=\"token operator\">&gt;<\/span> <span class=\"token number\">100<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            Debug<span class=\"token punctuation\">.<\/span><span class=\"token function\">LogWarning<\/span><span class=\"token punctuation\">(<\/span><span class=\"token interpolation-string\"><span class=\"token string\">$&#034;[MMAP] majflt burst: &#043;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span><span class=\"token expression language-csharp\">delta<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">\/s&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            Breadcrumb<span class=\"token punctuation\">.<\/span><span class=\"token function\">Mark<\/span><span class=\"token punctuation\">(<\/span>Crumb<span class=\"token punctuation\">.<\/span>MajorFaultBurst<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token keyword\">ushort<\/span><span class=\"token punctuation\">)<\/span>delta<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">static<\/span> <span class=\"token return-type class-name\"><span class=\"token keyword\">long<\/span><\/span> <span class=\"token function\">ReadMajFlt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token class-name\"><span class=\"token keyword\">var<\/span><\/span> f <span class=\"token operator\">&#061;<\/span> File<span class=\"token punctuation\">.<\/span><span class=\"token function\">ReadAllText<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;\/proc\/self\/stat&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">Split<\/span><span class=\"token punctuation\">(<\/span><span class=\"token char\">&#039; &#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">long<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">Parse<\/span><span class=\"token punctuation\">(<\/span>f<span class=\"token punctuation\">[<\/span><span class=\"token number\">11<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>   <span class=\"token comment\">\/\/ \u7b2c 12 \u4e2a\u5b57\u6bb5&#xff08;0-based \u7d22\u5f15 11&#xff09;<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">;<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h2>\u7b2c 8 \u7ae0&#xff1a;\u9677\u9631\u6e05\u5355<\/h2>\n<table>\n<tr>\u9677\u9631\u75c7\u72b6\u89e3\u6cd5<\/tr>\n<tbody>\n<tr>\n<td>\u672a ftruncate \u5c31 mmap<\/td>\n<td>SIGBUS&#xff08;\u4e0d\u662f SEGV&#xff0c;\u66f4\u96be\u67e5&#xff09;<\/td>\n<td>mmap \u524d\u5fc5\u987b\u5148\u8bbe\u7f6e\u6587\u4ef6\u5927\u5c0f<\/td>\n<\/tr>\n<tr>\n<td>MAP_PRIVATE \u5199\u5165<\/td>\n<td>\u5185\u5b58\u7ffb\u500d&#xff08;COW&#xff09;&#xff0c;\u6587\u4ef6\u91cc\u4ec0\u4e48\u90fd\u6ca1\u6709<\/td>\n<td>\u8981\u5199\u5c31\u7528 MAP_SHARED<\/td>\n<\/tr>\n<tr>\n<td>\u53ea\u8bfb\u8d44\u6e90\u4e0d\u5c0f\u5fc3\u5199\u4e86<\/td>\n<td>PSS \u6084\u6084\u6da8&#xff0c;anon \u9875\u589e\u52a0<\/td>\n<td>\u7528 PROT_READ \u5f3a\u5236&#xff0c;\u5199\u5c31\u5d29\u6e83\u66b4\u9732\u95ee\u9898<\/td>\n<\/tr>\n<tr>\n<td>offset \u672a\u9875\u5bf9\u9f50<\/td>\n<td>mmap \u8fd4\u56de EINVAL<\/td>\n<td>offset \u5bf9\u9f50\u5230 sysconf(_SC_PAGESIZE)<\/td>\n<\/tr>\n<tr>\n<td>APK \u5185\u6761\u76ee\u88ab\u538b\u7f29<\/td>\n<td>LoadFromFile \u9000\u5316\u4e3a\u5168\u91cf\u89e3\u538b<\/td>\n<td>gradle noCompress \u914d\u7f6e<\/td>\n<\/tr>\n<tr>\n<td>\u6218\u6597\u4e2d major fault \u98ce\u66b4<\/td>\n<td>\u968f\u673a 40~90ms \u5361\u987f&#xff0c;Profiler \u770b\u4e0d\u51fa<\/td>\n<td>\u52a0\u8f7d\u671f posix_fadvise \u9884\u70ed<\/td>\n<\/tr>\n<tr>\n<td>\u5207\u540e\u53f0\u518d\u56de\u6765\u5361<\/td>\n<td>\u9875\u88ab\u56de\u6536&#xff0c;\u91cd\u65b0 fault<\/td>\n<td>\u56de\u524d\u53f0\u65f6\u540e\u53f0\u7ebf\u7a0b\u91cd\u65b0\u9884\u70ed<\/td>\n<\/tr>\n<tr>\n<td>mlock \u60f3\u9489\u4f4f\u9875<\/td>\n<td>\u53cd\u800c\u66f4\u5bb9\u6613\u88ab LMK \u6574\u4f53\u6740\u6389<\/td>\n<td>\u7528 MADV_WILLNEED \u4ee3\u66ff<\/td>\n<\/tr>\n<tr>\n<td>\u5916\u90e8\u5b58\u50a8 mmap<\/td>\n<td>fault \u6210\u672c 2~5 \u500d<\/td>\n<td>\u70ed\u6570\u636e\u5fc5\u987b\u653e \/data \u5185\u90e8\u5b58\u50a8<\/td>\n<\/tr>\n<tr>\n<td>\u5171\u4eab\u5185\u5b58\u5b58\u6307\u9488<\/td>\n<td>\u53e6\u4e00\u8fdb\u7a0b\u89e3\u5f15\u7528\u5d29\u6e83<\/td>\n<td>\u53ea\u5b58\u504f\u79fb\u91cf<\/td>\n<\/tr>\n<tr>\n<td>\u5c0f\u6587\u4ef6 mmap<\/td>\n<td>\u6bd4 read \u8fd8\u6162<\/td>\n<td>&lt; 64KB \u7684\u6587\u4ef6\u76f4\u63a5 read<\/td>\n<\/tr>\n<tr>\n<td>VMA \u6570\u91cf\u7206\u70b8<\/td>\n<td>fault \u53d8\u6162&#xff0c;\/proc\/pid\/maps \u51e0\u5343\u884c<\/td>\n<td>\u5408\u5e76\u6210\u5927 pack &#043; offset<\/td>\n<\/tr>\n<tr>\n<td>msync(MS_SYNC) \u6bcf\u6b21\u8c03<\/td>\n<td>\u53d8\u6210\u540c\u6b65 IO&#xff0c;\u5361\u7206<\/td>\n<td>\u7528 MS_ASYNC&#xff0c;\u53ea\u5728\u5173\u952e\u70b9\u7528 SYNC<\/td>\n<\/tr>\n<tr>\n<td>\u5fd8\u8bb0 munmap<\/td>\n<td>\u865a\u62df\u5730\u5740\u7a7a\u95f4\u8017\u5c3d&#xff08;32 \u4f4d\u5c24\u5176&#xff09;<\/td>\n<td>\u914d\u5bf9\u91ca\u653e&#xff1b;64 \u4f4d\u95ee\u9898\u5c0f\u4f46\u4ecd\u8981\u7ba1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h2>\u7ed3\u8bed<\/h2>\n<p>\u56de\u5230\u6807\u9898\u90a3\u53e5\u8bdd&#xff0c;\u73b0\u5728\u53ef\u4ee5\u5b8c\u6574\u89e3\u91ca\u4e86&#xff1a;<\/p>\n<p>\u201c\u8ba9\u7528\u6237\u7a7a\u95f4\u7684\u4e00\u6bb5\u865a\u62df\u5730\u5740\u76f4\u63a5\u6307\u5411\u5185\u6838\u7684 page cache\u201d<\/p>\n<p>&#061; \u5185\u6838\u5728\u4f60\u7684\u9875\u8868\u9879&#xff08;PTE&#xff09;\u91cc&#xff0c;\u5199\u5165\u4e86 page cache \u90a3\u4e2a struct page \u7684\u7269\u7406\u9875\u5e27\u53f7\u3002<\/p>\n<p>\u6ca1\u6709\u62f7\u8d1d&#xff0c;\u53ea\u6709\u4e00\u6b21\u9875\u8868\u5199\u5165\u3002<br \/>\n\u4ece\u6b64\u4f60\u7684\u865a\u62df\u5730\u5740\u548c\u5185\u6838\u7684 page cache \u7d22\u5f15&#xff0c;\u6307\u5411\u540c\u4e00\u5757\u7269\u7406\u5185\u5b58\u3002<\/p>\n<p>\u8fd9\u4e2a\u673a\u5236\u5e26\u6765\u4e09\u4e2a\u5c42\u6b21\u7684\u4ef7\u503c&#xff0c;\u4e5f\u5e26\u6765\u4e09\u4e2a\u5c42\u6b21\u7684\u4ee3\u4ef7&#xff1a;<\/p>\n<table>\n<tr>\u5c42\u6b21\u6536\u76ca\u4ee3\u4ef7<\/tr>\n<tbody>\n<tr>\n<td>\u5185\u5b58<\/td>\n<td>\u53ea\u6709\u8bbf\u95ee\u8fc7\u7684\u9875\u624d\u9a7b\u7559&#xff0c;PSS \u964d 10 \u500d<\/td>\n<td>\u865a\u62df\u5730\u5740\u7a7a\u95f4\u5360\u6ee1&#xff0c;VMA \u589e\u591a<\/td>\n<\/tr>\n<tr>\n<td>\u901f\u5ea6<\/td>\n<td>\u52a0\u8f7d &#061; \u5efa VMA&#xff0c;\u5fae\u79d2\u7ea7<\/td>\n<td>\u6210\u672c\u63a8\u8fdf\u5230 page fault&#xff0c;\u65f6\u673a\u4e0d\u53ef\u63a7<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u9760\u6027<\/td>\n<td>\u810f\u9875\u5f52\u5185\u6838&#xff0c;SIGKILL \u4e5f\u4e0d\u4e22<\/td>\n<td>\u5199\u56de\u65f6\u673a\u4e0d\u786e\u5b9a&#xff0c;\u9700\u8981 msync \u515c\u5e95<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u6700\u91cd\u8981\u7684\u4e00\u8bfe&#xff0c;\u6765\u81ea\u6848\u4f8b 2&#xff1a;<\/p>\n<p>mmap \u4e0d\u662f&#034;\u96f6\u6210\u672c&#034;&#xff0c;\u800c\u662f&#034;\u628a\u6210\u672c\u4ece\u4e00\u6b21\u96c6\u4e2d\u7684\u5927\u62f7\u8d1d&#xff0c;\u6362\u6210\u5206\u6563\u7684\u3001\u4e0d\u53ef\u9884\u6d4b\u7684 page fault&#034;\u3002<\/p>\n<p>\u5728\u52a0\u8f7d\u754c\u9762&#xff0c;\u5206\u6563\u7684 fault \u662f\u597d\u4e8b&#xff08;\u5185\u5b58\u4f4e\u3001\u542f\u52a8\u5feb&#xff09;\u3002<br \/>\n\u5728\u6218\u6597\u4e2d&#xff0c;\u4e0d\u53ef\u9884\u6d4b\u7684 fault \u662f\u707e\u96be&#xff08;\u5361\u987f\u65e0\u6cd5\u5f52\u56e0&#xff09;\u3002<\/p>\n<p>\u6240\u4ee5\u771f\u6b63\u7684\u5de5\u7a0b\u89e3\u6cd5\u4ece\u6765\u4e0d\u662f&#034;\u7528 mmap&#034;&#xff0c;\u800c\u662f&#xff1a;<br \/>\n\u7528 mmap \u6362\u5185\u5b58&#xff0c;\u7528\u9884\u70ed\u6362\u786e\u5b9a\u6027&#xff0c;\u7528 Private_Clean \u6362\u6d3b\u547d\u673a\u4f1a\u3002<\/p>\n<p>\u5982\u679c\u4f60\u7684\u5c04\u51fb\u9879\u76ee\u53ea\u505a\u4e00\u4ef6\u4e8b&#xff0c;\u5c31\u505a\u8fd9\u4e2a&#xff1a;<\/p>\n<p>LoadFromFile \u4e4b\u524d&#xff0c;\u5148\u5728\u540e\u53f0\u7ebf\u7a0b posix_fadvise(WILLNEED) \u628a\u672c\u5c40\u8d44\u6e90\u6572\u8fdb page cache\u3002 \u4e00\u4e2a\u51e0\u5341\u884c\u7684\u539f\u751f\u63d2\u4ef6&#xff0c;\u80fd\u628a\u6218\u6597\u5361\u987f P99 \u4ece 47ms \u964d\u5230 11ms\u3002<\/p>\n<hr \/>\n<h4>\u53c2\u8003\u8d44\u6e90<\/h4>\n<p>\u5185\u6838\u673a\u5236<\/p>\n<ul>\n<li>Linux man pages \u2014 mmap(2)\u3001madvise(2)\u3001posix_fadvise(2)\u3001msync(2)\u3001mincore(2)\u3001mlock(2)<\/li>\n<li>Linux Kernel Docs \u2014 Memory Management&#xff08;vm_area_struct\u3001address_space\u3001page cache \u4e0e XArray&#xff09;<\/li>\n<li>\u5185\u6838\u6e90\u7801\u8def\u5f84 \u2014 mm\/filemap.c: filemap_fault()\u3001mm\/memory.c: handle_mm_fault() \/ do_fault_around() \/ do_wp_page()<\/li>\n<li>LWN.net \u2014 Fault-around\u3001Page reclaim and the LRU lists\u3001Transparent huge pages<\/li>\n<li>Mel Gorman \u2014 Understanding the Linux Virtual Memory Manager<\/li>\n<\/ul>\n<p>Android \u5e73\u53f0<\/p>\n<ul>\n<li>Android Developers \u2014 Memory allocation among processes\u3001Process importance &amp; LMK<\/li>\n<li>Android NDK \u2014 ASharedMemory\u3001AHardwareBuffer<\/li>\n<li>Android \u2014 Support 16 KB page sizes&#xff08;Android 15 arm64 \u5bf9\u9f50\u8981\u6c42&#xff09;<\/li>\n<li>\/proc\/&lt;pid&gt;\/smaps\u3001smaps_rollup\u3001stat&#xff08;minflt\/majflt&#xff09;\u5b57\u6bb5\u8bf4\u660e<\/li>\n<li>zipalign \u4e0e APK \u5185 STORED \u6761\u76ee\u53ef mmap \u7684\u524d\u63d0<\/li>\n<\/ul>\n<p>Unity<\/p>\n<ul>\n<li>Unity Manual \u2014 AssetBundle compression&#xff08;Uncompressed \/ LZ4 \/ LZMA \u7684\u52a0\u8f7d\u884c\u4e3a\u5dee\u5f02&#xff09;<\/li>\n<li>Unity Scripting API \u2014 AssetBundle.LoadFromFile(path, crc, offset)<\/li>\n<li>Unity Manual \u2014 Android: Split Application Binary\u3001gradle noCompress \u914d\u7f6e<\/li>\n<\/ul>\n<p>\u6027\u80fd\u6d4b\u91cf<\/p>\n<ul>\n<li>Perfetto \u2014 \u7cfb\u7edf\u7ea7 tracing&#xff0c;\u53ef\u89c2\u5bdf page fault \u4e0e IO \u963b\u585e<\/li>\n<li>Android simpleperf \u2014 CPU \u91c7\u6837&#xff08;\u6ce8\u610f&#xff1a;\u7761\u7720\u7b49 IO \u7684\u65f6\u95f4\u91c7\u6837\u5668\u770b\u4e0d\u5230&#xff09;<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>mmap \u7684\u5e95\u5c42\u771f\u76f8&#xff0c;\u4ee5\u53ca\u5c04\u51fb\u6e38\u620f\u91cc\u7684\u6bcf\u4e00\u6b21\u4ee3\u4ef7\u7b2c 0 \u7ae0&#xff1a;\u5148\u5efa\u7acb\u76f4\u89c9<br \/>\n0.1 \u4e00\u4e2a\u6bd4\u55bb&#xff1a;\u540c\u4e00\u672c\u4e66&#xff0c;\u4e24\u4e2a\u95e8\u724c\u53f7<br \/>\n\u56fe\u4e66\u9986\u6709\u4e00\u672c\u4e66&#xff0c;\u7f16\u53f7 \u7269\u7406\u4e66\u67b6 P7\u3002<br \/>\n\u8bfb\u8005 A \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;\\&#8221;\u7b2c 3 \u53f7\u9605\u89c8\u684c\\&#8221;<br \/>\n\u8bfb\u8005 B \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;\\&#8221;\u7b2c 9 \u53f7\u9605\u89c8\u684c\\&#8221;<br \/>\n\u56fe\u4e66\u9986\u7ba1\u7406\u7cfb\u7edf\u91cc\u8bb0\u7740&#xff1a; \\&#8221;\u7269\u7406\u4e66\u67b6 P7\\&#8221;\u4e09\u4e2a\u4e0d\u540c\u7684\\&#8221;\u5730\u5740\\&#8221;&#xff0c;\u6307\u5411\u540c\u4e00\u672c\u4e66\u3002\u8fd9\u5c31\u662f\u865a\u62df\u5185\u5b58&#xff1a;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[11786],"topic":[],"class_list":["post-103374","post","type-post","status-publish","format-standard","hentry","category-server","tag-mmap"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/103374.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"mmap \u7684\u5e95\u5c42\u771f\u76f8&#xff0c;\u4ee5\u53ca\u5c04\u51fb\u6e38\u620f\u91cc\u7684\u6bcf\u4e00\u6b21\u4ee3\u4ef7\u7b2c 0 \u7ae0&#xff1a;\u5148\u5efa\u7acb\u76f4\u89c9 0.1 \u4e00\u4e2a\u6bd4\u55bb&#xff1a;\u540c\u4e00\u672c\u4e66&#xff0c;\u4e24\u4e2a\u95e8\u724c\u53f7 \u56fe\u4e66\u9986\u6709\u4e00\u672c\u4e66&#xff0c;\u7f16\u53f7 \u7269\u7406\u4e66\u67b6 P7\u3002 \u8bfb\u8005 A \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;&quot;\u7b2c 3 \u53f7\u9605\u89c8\u684c&quot; \u8bfb\u8005 B \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;&quot;\u7b2c 9 \u53f7\u9605\u89c8\u684c&quot; \u56fe\u4e66\u9986\u7ba1\u7406\u7cfb\u7edf\u91cc\u8bb0\u7740&#xff1a; &quot;\u7269\u7406\u4e66\u67b6 P7&quot;\u4e09\u4e2a\u4e0d\u540c\u7684&quot;\u5730\u5740&quot;&#xff0c;\u6307\u5411\u540c\u4e00\u672c\u4e66\u3002\u8fd9\u5c31\u662f\u865a\u62df\u5185\u5b58&#xff1a;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/103374.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-10T03:09:09+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/103374.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/103374.html\",\"name\":\"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-09-10T03:09:09+00:00\",\"dateModified\":\"2026-09-10T03:09:09+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/103374.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/103374.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/103374.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/103374.html","og_locale":"zh_CN","og_type":"article","og_title":"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"mmap \u7684\u5e95\u5c42\u771f\u76f8&#xff0c;\u4ee5\u53ca\u5c04\u51fb\u6e38\u620f\u91cc\u7684\u6bcf\u4e00\u6b21\u4ee3\u4ef7\u7b2c 0 \u7ae0&#xff1a;\u5148\u5efa\u7acb\u76f4\u89c9 0.1 \u4e00\u4e2a\u6bd4\u55bb&#xff1a;\u540c\u4e00\u672c\u4e66&#xff0c;\u4e24\u4e2a\u95e8\u724c\u53f7 \u56fe\u4e66\u9986\u6709\u4e00\u672c\u4e66&#xff0c;\u7f16\u53f7 \u7269\u7406\u4e66\u67b6 P7\u3002 \u8bfb\u8005 A \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;\"\u7b2c 3 \u53f7\u9605\u89c8\u684c\" \u8bfb\u8005 B \u7684\u501f\u4e66\u5355\u4e0a\u5199\u7740&#xff1a;\"\u7b2c 9 \u53f7\u9605\u89c8\u684c\" \u56fe\u4e66\u9986\u7ba1\u7406\u7cfb\u7edf\u91cc\u8bb0\u7740&#xff1a; \"\u7269\u7406\u4e66\u67b6 P7\"\u4e09\u4e2a\u4e0d\u540c\u7684\"\u5730\u5740\"&#xff0c;\u6307\u5411\u540c\u4e00\u672c\u4e66\u3002\u8fd9\u5c31\u662f\u865a\u62df\u5185\u5b58&#xff1a;","og_url":"https:\/\/www.wsisp.com\/helps\/103374.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-09-10T03:09:09+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"16 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/103374.html","url":"https:\/\/www.wsisp.com\/helps\/103374.html","name":"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-09-10T03:09:09+00:00","dateModified":"2026-09-10T03:09:09+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/103374.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/103374.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/103374.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"mmap\u7684\u771f\u76f8\uff1a\u4e0d\u62f7\u8d1d\uff0c\u53ea\u6620\u5c04"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/103374","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=103374"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/103374\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=103374"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=103374"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=103374"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=103374"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}