מה באמת אומר Memory Usage ב-Windows — איך לקרוא Working Set, Private Bytes, Commit ו-pagefile

· עודכן בתאריך: · · Windows, Windows development, memory management, Working Set, Private Bytes, Commit, pagefile, performance monitoring, troubleshooting, Sysinternals

היסטוריית עדכונים (גרסה ראשונה, פורסמה בתאריך 4 Aug 2026)
פרסום ראשון
לצטט את המאמר הזה(DOI: 10.5281/zenodo.22175966)

מאמר זה מאוחסן בארכיון Zenodo. להלן גם ה-DOI שתמיד מפנה לגרסה האחרונה וגם ה-DOI המקובע לגרסה שאתם קוראים.

Go Komura (2026). מה באמת אומר Memory Usage ב-Windows — איך לקרוא Working Set, Private Bytes, Commit ו-pagefile. KomuraSoft LLC. https://doi.org/10.5281/zenodo.22175966 https://comcomponent.com/he/blog/windows-memory-usage-working-set-commit/

DOI (הגרסה האחרונה)
10.5281/zenodo.22175966
DOI (הגרסה הזו)
10.5281/zenodo.22175967

ב-Task Manager מופיע ש-Memory של process מסוים הוא 1.2GB. ב-Process Explorer, לעומת זאת, Working Set הוא 1.5GB, Private Bytes הוא 2.4GB, וב-VMMap ה-Size גדול עוד יותר. ברמת המערכת מופיע “Committed 19.6/31.8GB”.

אז כמה GB של זיכרון האפליקציה הזו באמת צורכת?

התשובה: המספר שצריך להסתכל עליו תלוי במה שרוצים לדעת. מדד השימוש משתנה לפי השאלה — כמה resident ב-RAM עכשיו, כמה הוקצה באופן פרטי ל-process הזה, כמה Commit Charge המערכת כבר סופרת, או רק איזה טווח virtual addresses שמור.

מה שמבלבל במדדי הזיכרון של Windows הוא שהכול מוצג תחת אותה מילה, Memory, אף שהם מודדים צירים נפרדים:

  • כמה address space בשימוש
  • כמה Commit נצרך
  • האם זה כרגע resident ב-RAM הפיזי
  • האם ה-page פרטי ל-process, או shareable
  • כמה allocation נוספת המערכת כולה עוד יכולה לתמוך בה

המאמר מיועד למי שבודק גידול זיכרון באפליקציה או מחסור בזיכרון ברמת המערכת ב-Windows 10/11 וב-Windows Server הנוכחי, ומחבר בתמונה אחת את הקשרים בין Working Set, Private Working Set, Private Bytes, Commit, Virtual Bytes, pagefile, Available ו-Page Fault.

את הליך המעקב אחרי אובייקטי .NET שלא נאספים מכסה בפירוט “להבחין בין עיכוב GC ל-memory leak ב-.NET”, ואת ההפעלה המעשית של VMMap ו-Process Explorer מכסה “Process Explorer / Handle / VMMap בפועל”. המאמר הזה מתרכז בתנאי המוקדם של שניהם: איך לקרוא את המספרים מצד מערכת ההפעלה Windows.

1. השורה התחתונה קודם

  • Working Set הוא קבוצת ה-pages שכרגע resident ב-RAM. הוא כולל לא רק pages פרטיים ל-process אלא גם pages שאפשר לשתף עם processes אחרים, כמו קוד DLL ו-memory-mapped files.1
  • Private Working Set הוא החלק מתוך ה-Working Set שכרגע שייך רק לאותו process. הוא שימושי כקירוב ל-“ה-RAM ש-process זה לבדו תופס כרגע”, אבל זו לא הכמות הכוללת שהאפליקציה הקצתה.2
  • Private Bytes הוא כמות ה-Commit הפרטית לאותו process. זה מדד נפרד משאלה אם הזיכרון כרגע resident ב-RAM. גם השדה PagefileUsage במבנה של Win32 API מייצג, ב-Windows הנוכחי, בפועל את אותו Commit Charge, ואינו מספר הבתים שנכתבו בפועל ל-pagefile.2
  • “Committed X/Y” ב-Task Manager מציג את X כסך ה-Commit הנוכחי של המערכת ואת Y כתקרת ה-Commit. X אינו שימוש ב-pagefile. Y נקבע בערך לפי RAM ועוד pagefile.3
  • Reserve ו-Commit הם דברים שונים. שמירה בלבד של טווח virtual addresses מניחה את הטווח בצד לשימוש עתידי; היא לא צורכת את אותה כמות לא של RAM ולא של תקרת ה-Commit.45
  • Page Fault אינו בהכרח I/O לדיסק. יש soft fault, שאפשר לפתור בתוך ה-RAM, ו-hard fault שקורא מ-pagefile, מקובצי הרצה, מ-memory-mapped files וכדומה.16
  • memory leak נשפט לא מקריאה אחת אלא מהמגמה כשחוזרים על אותו עומס. בפרט, עקבו אם Private Bytes והפירוט שלו ממשיכים לטפס במדרגות גם אחרי שהעיבוד נגמר, בלי לחזור לאותו steady state.

במשפט אחד: Working Set הוא “הכמות שנמצאת כרגע ב-RAM”, Private Bytes הוא “ה-Commit הפרטי ל-process הזה”, ו-Commit הוא “הכמות ש-committed ברמת המערכת”.

בחירת מדד הזיכרון הנכון של Windowsאיזה מדד לבדוק תלוי בשאלה אם רוצים residency ב-RAM, Commit פרטי ל-process, Commit ברמת המערכת, או טווח virtual addressesהכמות כרגע ב-RAMCommit הפרטי ל-processCommit ברמת המערכתטווח כתובות reservedמה רוצים לדעת על Memory UsageWorking SetPrivate BytesSystem CommitVirtual Bytes / Reservedresident ב-RAM פיזיCommit פרטי ל-processהשוואה מול Commit Limitvirtual address space

איור 1: פרקו תחילה את התצפית “הזיכרון גבוה” לארבע שאלות נפרדות.

2. פיצול Memory Usage לארבעה צירים

בהתחלה, חשבו על זיכרון Windows לא כעל “פס אחד” אלא לאורך ארבעה צירים.

ארבעה צירים עצמאיים לסיווג page אחדבדקו בנפרד את מצב ה-virtual address, את ה-backing של pages committed, את ה-residency ב-RAM הפיזי, ואת אפשרות השיתוף עם processes אחריםהסתכלו על page אחד בארבעה ציריםמצב הכתובתFree / Reserved / CommittedbackingPage-file-backed / File-backedresidency ב-RAMResident / Not residentאפשרות שיתוףPrivate / Shareable

איור 2: גם ב-page אחד, מצב הכתובת, ה-backing, ה-residency ואפשרות השיתוף נקבעים כל אחד בנפרד.

Mapped אינו מצב כתובת לצד Free, Reserved ו-Committed — זו קטגוריה של אזור. גם pages ב-mapped view יכולים להיות Committed. באותו אופן, Private אינו מדיום backing אלא סיווג של אפשרות שיתוף. לכן קראו backing כ-Page-file-backed או File-backed, ואפשרות שיתוף כ-Private או Shareable, בנפרד.

צירוף ארבעת הצירים האלה נותן את הקשר בין המדדים הייצוגיים כך.

מצב ה-page Working Set Private Working Set Private Bytes משפחת Virtual Bytes
פרטי ל-process, committed, resident ב-RAM כלול כלול כלול כלול
פרטי ל-process, committed, לא resident ב-RAM אינו כלול אינו כלול כלול כלול
shared page של DLL או mapped file, resident ב-RAM כלול בדרך כלל אינו כלול בדרך כלל אינו כלול כלול
Reserved אבל לא committed אינו כלול אינו כלול אינו כלול עשוי להיכלל
טווח כתובות שאינו בשימוש אינו כלול אינו כלול אינו כלול בדרך כלל אינו כלול
מיפוי סוגי pages למדדי הזיכרון העיקרייםמראה אילו מדדים כוללים pages פרטיים resident, pages פרטיים שאינם resident, shared pages resident, וטווחים reserved בלבדPrivate, committed, resident ב-RAMPrivate, committed, לא resident ב-RAMshared page, resident ב-RAMReserved, לא committedWorking SetPrivate Working SetPrivate Bytesמשפחת Virtual Bytes

איור 3: Working Set ו-Private Bytes סופרים קבוצות pages שונות, ולכן אין ביניהם יחס הכלה פשוט.

הנקודה החשובה כאן היא שWorking Set ו-Private Bytes אינם ביחס הכלה פשוט.

Private Bytes כולל pages שפרטיים ל-process אבל כרגע לא resident ב-RAM. Working Set, לעומת זאת, כולל shared pages — כמו קוד DLL וזיכרון משותף — ש-Private Bytes לא סופר בכלל. לכן, לפי ה-process ולפי הרגע, Working Set יכול להיות גדול מ-Private Bytes, או ההפך.

כמו כן, סיכום פשוט של ה-Working Set של כמה processes יכול לספור את אותו page פיזי — למשל DLL משותף — יותר מפעם אחת. “סכום ה-Working Set של כל process שווה ל-RAM שבשימוש” לא בהכרח מחזיק.

3. virtual address space —‏ Reserve ו-Commit הם דברים שונים

3.1. virtual address אינה כתובת RAM פיזית

לכל process יש virtual address space פרטי משלו. pointer שהאפליקציה עובדת איתו לא מצביע ישירות על מיקום ב-RAM הפיזי; Windows משתמש ב-page tables כדי למפות virtual addresses ל-pages פיזיים או לנתונים בקובץ.7

כתוצאה מכך, גם במחשב עם 64GB RAM מותקן, ה-virtual address space ש-process נתון של 32-bit יכול להשתמש בו קטן בהרבה בדרך כלל. ולהפך, זה גם נורמלי ש-process של 64-bit יהיה בעל virtual address space גדול מה-RAM הפיזי.

3.2. Reserved אומר רק ש”הכתובת נתפסה”

MEM_RESERVE של VirtualAlloc שומר טווח virtual addresses רציף לשימוש עתידי. בשלב הזה אין physical storage שמשויך ל-pages, ואי אפשר לקרוא מהטווח או לכתוב אליו.45

למשל, גם אם database או runtime שומר טווח כתובות של 8GB לצמיחה עתידית, זה לבדו לא צורך 8GB של RAM או 8GB של Private Bytes.

3.3. Committed פירושו שיש backing כשיהיה צורך

MEM_COMMIT היא הפעולה שמעבירה virtual page למצב Committed וגורמת ל-Windows לספור את ה-backing הדרוש. האם קריאה, כתיבה או הרצה מותרות בפועל נקבע בנפרד לפי הגנת ה-page — PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE, PAGE_NOACCESS וכן הלאה — כך ש-Committed כשלעצמו לא אומר “ניתן לקריאה ולכתיבה”. ברגע ה-commit זה נספר ל-Commit Charge של המערכת, אבל ה-page הפיזי בפועל עשוי לא להיות מוקצה עד הגישה הראשונה. page שנוגעים בו בפעם הראשונה מאותחל באפסים, עובר demand-zero fault, ונכנס ל-Working Set.51

לכן, אף שקוראים לזה “הוקצה” בשני המקרים, בפועל יש שלושת השלבים הבאים.

שלושה שלבים מ-Reserve דרך Commit ל-residency ב-RAMמראה את הזרימה של שמירת virtual address, commit של ה-page, והקצאת page פיזי בגישה הראשונה עם כניסה ל-Working SetMEM_COMMITגישה ראשונה, demand-zero faultאם לא ניגשו מעולםMEM_RESERVE - שמירת טווח כתובותמשתקף במשפחת Virtual BytesCommitted - נגיש לפי הגנת ה-pageמשתקף ב-Private Bytes / System Commitהוקצה page פיזי, resident ב-RAMמשתקף ב-Working SetCommitted אבל לא resident

איור 4: Reserve, Commit והגישה הראשונה הם אירועים נפרדים, וכל אחד מזיז מדד אחר.

שלושת השלבים האלה מזיזים בנפרד, בהתאמה, את המספרים של משפחת Virtual Bytes, של Private Bytes ושל Working Set.

3.4. למה אפשר לקבל OutOfMemory גם כשיש RAM פנוי

האם הקצאת זיכרון מצליחה לא נקבע לפי RAM פנוי לבדו.

  • ה-process כילה את ה-virtual address space שלו
  • אין טווח כתובות פנוי בגודל הנדרש שהוא רציף
  • ה-Commit Charge ברמת המערכת הגיע ל-Commit Limit
  • ל-Job Object, ל-container, ל-runtime או ל-library יש מגבלה משלהם
  • זה process של 32-bit
  • ה-native heap מפורק (fragmented)

גם ב-Windows של 64-bit, ה-user-mode virtual address space של process של 32-bit הוא בדרך כלל 2GB אם IMAGE_FILE_LARGE_ADDRESS_AWARE אינו מוגדר. אפליקציית 32-bit עם הדגל הזה יכולה להשתמש עד 4GB ב-Windows של 64-bit.8

לכן “למחשב יש 20GB של RAM פנוי, ובכל זאת אפליקציית ה-32-bit נכשלת סביב 1.6GB” אינו סתירה. זו אולי כלל לא בעיית RAM, אלא fragmentation של ה-address space או פגיעה במגבלה קשיחה.

4. Working Set —‏ pages שנמצאים כרגע ב-RAM

Working Set הוא קבוצת ה-pages, בתוך ה-virtual address space של process, שכרגע resident ב-RAM הפיזי.1

הקבוצה הזו היא תערובת של הבאים.

  • ה-heap וה-stack של ה-process עצמו
  • קוד EXE ו-DLL ונתונים לקריאה בלבד
  • memory-mapped files
  • shared memory
  • pages שהפכו פרטיים לאותו process אחרי copy-on-write
  • pages ש-runtime ו-libraries שונות נגעו בהם

4.1. Working Set שגדל אינו בהכרח אומר שהוקצה יותר

גישה בפעם הראשונה ל-page שכבר היה committed יכולה להגדיל את ה-Working Set לבדו בזמן ש-Private Bytes נשאר בלי שינוי. באותו אופן, כשקובץ גדול ממופה לזיכרון ונקרא ברצף, pages עם file backing נכנסים ל-Working Set בזמן ש-Private Bytes כמעט לא גדל.

ולהפך, כש-Windows עושה Trim ל-Working Set בתגובה ללחץ זיכרון, ה-Working Set לבדו מצטמק בזמן שהאפליקציה מחזיקה לוגית את אותו זיכרון. נגיעה חוזרת אחר כך מחזירה אותו דרך Page Fault.

לכן ירידה ב-Working Set לא בהכרח אומרת “האפליקציה שחררה”, ועלייה לא בהכרח אומרת “האפליקציה הקצתה מחדש”.

זרימה טיפוסית שבה רק ה-Working Set עולה ויורדאותו page committed נכנס ל-RAM בגישה הראשונה, מפסיק להיות resident ב-Trim, וחוזר בגישה חוזרת, בזמן ש-Private Bytes ממשיך להיספרגישה ראשונהTrim תחת לחץ זיכרוןPage Fault בגישה חוזרתאותו page committedresident ב-RAMלא residentכלול ב-Working Setאינו כלול ב-Working Setנספר ב-Private Bytes כל עוד committed

איור 5: Working Set עולה ויורד עם ה-residency, אבל Private Bytes לא יורד כל עוד ה-Commit על אותו page נשאר.

4.2. Working Set כולל shared pages

אם 10 processes חולקים את דפי הקוד של אותו DLL, ה-page הזה יכול להופיע ב-Working Set של כל process, אף שבעותק אחד בלבד קיים ב-RAM הפיזי. סכום Working Set שחורג מה-RAM המותקן אינו מיד סימן לבעיה.

אם רוצים להתקרב ל-“ה-RAM ש-process זה לבדו תופס כרגע”, הסתכלו על Private Working Set. גם אז, זה אינו “כל הזיכרון שאותו process הקצה” — זה בדיוק ה-pages הפרטיים שכרגע resident.

4.3. הורדה בכפייה של ה-Working Set לא מתקנת memory leak

אפשר להשתמש ב-EmptyWorkingSet או ב-SetProcessWorkingSetSize כדי לפנות pages מ-Working Set של process. אבל זו לא פעולה שמשחררת Commit או משחררת הפניות ב-heap. שימוש ה-RAM הנראה יורד בזמן ש-Private Bytes נשאר בלי שינוי, והגישה הבאה יכולה להפעיל פרץ של Page Faults.9

אם הנתון ב-Task Manager מצטמק רק מיד אחרי שלוחצים על כפתור “הפחתת זיכרון”, ומיד עולה בחזרה כשחוזרים לעבוד, זה עשוי להיות רק Trim של Working Set ולא “שחרור” אמיתי.

5. Private Bytes — כמות ה-Commit הפרטית ל-process

Private Bytes הוא כמות ה-virtual memory ש-committed באופן בלעדי לאותו process. הוא מייצג Commit Charge שאי אפשר לשתף עם process אחר, ולא משנה אם הוא כרגע resident ב-RAM. ב-PROCESS_MEMORY_COUNTERS_EX של Microsoft, PrivateUsage מתאים לערך הזה.102

ל-Win32 API יש גם שדה בשם מבלבל, PagefileUsage, אבל התיעוד הנוכחי מגדיר אותו כ-“Commit Charge של אותו process” וקובע שזה אותו ערך כמו PrivateUsage. במילים אחרות, Private Bytes של 2GB אינו אומר “נכתבו 2GB ל-pagefile.sys”.2

Private Bytes מושפע בדרך כלל מהבאים.

  • Commit של ה-native heap שמשמשים HeapAlloc, malloc, new ודומיהם
  • Private Data ש-committed ישירות עם VirtualAlloc
  • האזור ה-committed של ה-GC heap של .NET
  • החלק מ-thread stack ש-committed בפועל
  • ה-Commit Charge לכל ה-view שנשמר כשממפים תצוגת copy-on-write (FILE_MAP_COPY)
  • buffers פרטיים ש-libraries ו-SDK של התקנים מחזיקים בפנים

בתצוגת copy-on-write שנוצרת עם FILE_MAP_COPY, כל page יכול בסופו של דבר להפוך לפרטי, ולכן בזמן המיפוי Windows שומר Commit Charge מספיק כדי לגבות את כל ה-view ב-pagefile. בגלל זה System Commit ו-Commit Charge של ה-process (Private Bytes) יכולים לעלות בגודל כל ה-view עוד לפני שכתיבה כלשהי יוצרת בפועל עותק פרטי.11

5.1. למה Private Bytes לא יורד אחרי free או GC

גם כשהזיכרון “משוחרר” מנקודת המבט של האפליקציה, ה-runtime או ה-heap allocator עשויים שלא לעשות Decommit של האזור בחזרה ל-OS, אלא להחזיק אותו לשימוש חוזר עתידי. במקרה כזה Private Bytes נשאר גבוה אף שהאזור ניתן לשימוש חוזר בפנים בתוך האפליקציה.

הוא יכול גם להישאר גבוה מסיבות כמו שרק חלק מאזור גדול עדיין חי, fragmentation, או cache או pool שהתחממו עד התקרה.

לכן Private Bytes גבוה לבדו לא מוכיח memory leak. מה שצריך לבדוק הוא השוואה לאורך זמן:

  1. חזרו על אותו עיבוד אותו מספר פעמים
  2. המתינו אותו זמן אחרי העיבוד
  3. בדקו אם Private Bytes חוזר לאותה רמה, או מתייצב על ערך קבוע
  4. השתמשו ב-VMMap או ב-heap dump כדי לבדוק איזה אזור או סוג גדל
למה Private Bytes לא יורד אחרי free או GCPrivate Bytes משתנה אחרת בהתאם לשאלה אם ה-allocator מחזיר ל-OS אזור שהאפליקציה כבר לא צריכה, או מחזיק אותו לשימוש חוזרDecommit / Releaseמחזיק לשימוש חוזרהאפליקציה משחררת אזור דרך free / GCהאם ה-allocator מחזיר אותו ל-OSCommit Charge יורדPrivate Bytes יורדהאזור נשאר committedPrivate Bytes נשאר גבוהpools, caches, fragmentation

איור 6: אזור שהפך ניתן לשימוש חוזר בתוך האפליקציה אינו אותו דבר כמו החזרת ה-Commit שלו ל-OS.

5.2. תבנית מועמדת חזקה ל-memory leak

עלייה כמו הבאה, שבה ה-baseline עולה במדרגות עם כל סבב עומס, ראויה לתשומת לב.

Private Bytes
  ^
  |                    ________
  |             ______|
  |      ______|
  |_____|
  +----------------------------> חזרות על אותו עיבוד

עם זאת, גם צורת מדרגות יכולה להיות רק כמה סבבי צמיחה מ-JIT בפעם הראשונה, גופנים, image decoders, connection pools או cache warmup, ואחריהם היא מתייצבת. מה שחשוב אינו שהיא גדלה, אלא שהיא נכשלת להתכנס ל-steady state.

6. System Commit — מה באמת “Committed X/Y”

הנתון “Committed X/Y” בלשונית [Performance] ← [Memory] של Task Manager הוא מדד ברמת המערכת.

  • X: System Commit Charge — ה-committed memory ש-Windows סופר כרגע כ-Commit Charge בכל המערכת
  • Y: System Commit Limit — תקרת ה-Commit שהמערכת יכולה לתמוך בה

Commit Limit נקבע בערך לפי RAM פיזי ועוד סך כל ה-pagefiles. בלי pagefile, הוא יוצא קצת קטן מה-RAM המותקן.36

הקשר בין System Commit Charge ל-Commit LimitCommit פרטי לכל process, של shared sections ושל ה-kernel מרכיבים את הערך הנוכחי X, בעוד RAM פיזי ו-pagefile תומכים בתקרה YX לא יכול לעבור את YPrivate Commit של כל processSystem Commit Charge - XCommit של shared sections עם pagefile backingCommit של ה-kernelRAM פיזיSystem Commit Limit - Ypagefile

איור 7: X הוא כמות ה-Commit הנוכחית ו-Y הוא התקרה שיכולה לתמוך בה — זו לא תצוגה של שימוש ב-pagefile.

System Commit Charge כולל לא רק את סכום ה-Private Bytes של כל process, אלא גם את ה-Commit של shared sections שמגובים ב-pagefile ואת ה-Commit שה-kernel צורך. לכן סכום ה-Private Bytes לפי process לבדו לא יכול להסביר את X במלואו.

6.1. Commit Charge אינו שימוש ב-pagefile

קחו מערכת עם 16GB RAM, pagefile של 16GB, ו-Committed ב-20/31GB.

אותם 20GB לא אומרים “נכתבו 20GB ל-pagefile”. זו הכמות הכוללת ש-Windows סופר כ-Commit Charge — כלומר, ל-pages פרטיים הניתנים לכתיבה וכדומה, ייש backing של RAM או של pagefile כשיהיה צורך.

באותו רגע יכול להתקיים ערבוב של המצבים הבאים:

  • רובו resident ב-RAM
  • חלקו פונה ל-pagefile
  • חלקו committed אבל עדיין לא הייתה לו גישה ראשונה
  • חלקו נצרך כ-Commit מצד ה-kernel

אם רוצים לראות שימוש בפועל ב-pagefile, בדקו Paging File(*)\% Usage בנפרד מ-Commit. גם החומר של Microsoft עצמה מסביר ששימוש גבוה ב-pagefile לבדו לא בהכרח מעיד על בעיית ביצועים, ושצריך לשפוט אותו יחד עם הגעה ל-Commit Limit, עם Modified Page List ועם paging I/O בפועל.6

6.2. מה קורה כשמתקרבים ל-Commit Limit

כש-System Commit Charge מגיע ל-Commit Limit, אי אפשר לגבות בקשות commit חדשות. זה מוביל לכישלונות הקצאת זיכרון של processes, לקריסות אפליקציות ולמערכת שלא מגיבה.3

כאן X/Y של Commit חשוב יותר מ-“RAM פנוי”. גם אם עושים Trim ל-Working Set כדי לפנות RAM, הגעה ל-Commit Limit לא נפתרת אלא אם ה-Commit Charge עצמו יורד.

6.3. שלושת התפקידים של ה-pagefile

ה-pagefile משרת בעיקר את התפקידים הבאים.

  1. הרחבת ה-Commit Limit
  2. לאפשר לפנות מ-RAM pages שסומנו Modified ונמצאים בשימוש נדיר
  3. לגבות את ה-crash dump של המערכת, בהתאם להגדרה

השבתת pagefile אינה מקרה פשוט של “I/O לדיסק תמיד יורד והדברים נעשים מהירים יותר”. אם כבר, היא מורידה את ה-Commit Limit, מגדילה את הסיכוי ש-pages שסומנו Modified אבל כרגע אינם נחוצים יישארו ב-RAM, ויכולה להפוך לבלתי אפשרי לאסוף את ה-dump שצריך כשקריסה מתרחשת.36

את גודל ה-pagefile המתאים אי אפשר להחליט לפי ה-RAM המותקן לבדו. Microsoft עצמה מסבירה שאי אפשר להכליל, כי שיא ה-System Commit Charge וסוג ה-crash dump הנדרש שונים ממערכת למערכת.6

7. פירוט ה-RAM הפיזי — אל תשפטו מ-Available נמוך לבדו

RAM פיזי אינו משמש רק את ה-Working Set של user processes.

  • ה-Working Set של כל process
  • system file cache
  • page lists כמו Standby, Modified, Free ו-Zeroed
  • Paged Pool / Nonpaged Pool של ה-kernel
  • זיכרון שמחזיקים device drivers
  • מחסן דחיסת הזיכרון
  • אזורים משותפים עם ה-GPU והתקנים אחרים או שמורים להם
  • זיכרון ששמור לחומרה

7.1. Available כולל גם cache שניתן לשימוש חוזר

Available MBytes של Windows אינו פשוט RAM שאינו בשימוש כלל. זה מדד שכולל, לצד Free ו-Zeroed, גם Standby pages שאפשר להשתמש בהם מחדש אם צריך.12

  • Free: pages שאינם מוקצים כרגע לאף מטרה
  • Zeroed: pages שאופסו כך שאפשר למסור אותם בבטחה ל-process אחר
  • Standby: pages שעזבו Working Set אבל התוכן שלהם עדיין ב-cache ב-RAM
  • Modified: pages שהתוכן שלהם השתנה ושצריך לכתוב אותם ל-backing המתאים לפני שימוש חוזר
תנועה בין ה-Working Set ל-page listsמראה pages שלא השתנו שיוצאים ל-Standby ו-pages שסומנו Modified שיוצאים ל-Modified, ואז גישה חוזרת, כתיבה ושימוש חוזרהוסר page שלא השתנההוסר page שסומן Modifiedהכתיבה הושלמהגישה חוזרתשימוש חוזר למטרה אחרתאופסגישה אחרי הקצאהWorking Set - בשימושStandby - מועמד לשימוש חוזר עם תוכן שנשמרModified - ממתין לכתיבההוקצה למטרה אחרתFree - אינו בשימושZeroed - זמין להקצאה חדשהכלול ב-Available

איור 8: Available כולל לא רק זיכרון פנוי לגמרי אלא גם Standby, שאפשר להשתמש בו מחדש אם צריך.

“לזרוק את כל ה-cache כדי להגדיל RAM פנוי” אינו תמיד ניצחון. אם הנתונים שצריך עדיין יושבים ב-Standby, גישה חוזרת יכולה להחזיר אותם ל-Working Set במהירות בלי לקרוא מהדיסק.

לכן גם אם Free נמוך ב-Task Manager, אם Available מרווח ו-hard Page Faults או המתנות דיסק לא גורמות לבעיות, Windows פשוט עשוי להשתמש ב-RAM ביעילות כ-cache.

7.2. כשה-RAM מצטמק בלי process גדול

אין זה נדיר שצריכת זיכרון תישאר בלתי מוסברת גם אחרי שמחברים את ה-Private Working Set של כל process.

  • file cache ו-memory-mapped files
  • Nonpaged Pool / Paged Pool
  • pages שנעלו על ידי driver
  • shared pages
  • דחיסת זיכרון
  • allocations שקשורות לווירטואליזציה או ל-GPU

במקרה כזה, במקום להמשיך לבהות ברשימת ה-processes, בדקו Use Counts, Processes, Priority Summary ו-File Summary ב-RAMMap של Sysinternals. RAMMap הוא הכלי הרשמי לפירוק זיכרון פיזי לפי מטרה, page list וקובץ.13

אם רק Nonpaged Pool ממשיך לגדול, זו הנקודה שבה יש לחשוד ב-memory leak מצד driver או kernel, ולא ב-Private Bytes של אפליקציה ב-user mode.

8. Page Fault — ספירה גבוהה אינה חריגה כשלעצמה

Page Fault מתרחש כש-process ניגש ל-page שאינו כרגע ב-Working Set שלו. למרות המילה Fault בשם, זו לא כשל חריג — זה המנגנון הרגיל שמניע virtual memory.1

8.1. Soft page fault

אלה נפתרים בלי לקרוא מהדיסק.

  • ה-page עדיין ב-Standby או ב-Transition
  • אותו shared page כבר נמצא ב-Working Set של process אחר
  • ניגשים בפעם הראשונה ל-page committed ומוקצה page של אפסים
  • ה-prefetch של מנהל הזיכרון כבר הכניס אותו ל-RAM

לכן \Memory\Page Faults/sec גדול אינו בהכרח אומר שמתרחש I/O לדיסק או latency.

8.2. Hard page fault

אלה דורשים לקרוא תוכן מ-backing store בדיסק. המקור אינו מוגבל ל-pagefile.

  • קוד ונתונים ב-.exe או ב-.dll
  • memory-mapped file
  • pagefile
הענף בין soft page fault ל-hard page faultבגישה ל-page שאינו ב-Working Set, מטפלים כ-soft page fault אם אין צורך ב-storage I/O, או כ-hard page fault אם ישלא - Standby, shared, demand-zero וכוכןגישה ל-page שאינו ב-Working Setהאם נדרש storage I/OSoft page faultנכנס ל-Working Set בלי קריאת דיסקHard page faultמאיפה קוראיםEXE / DLLmemory-mapped filepagefileנכנס ל-Working Set אחרי טעינה

איור 9: השם Page Fault לבדו לא יכול לומר אם התרחש I/O לדיסק.

Microsoft מונה את \Memory\Pages/sec, \Memory\Page Reads/sec ו-\Memory\Pages Input/sec בין המונים למדידת hard fault. מכיוון שגובהם אינו בהכרח אומר שחסר זיכרון, קשרו אותם ל-Available MBytes, ל-disk latency ולזמן תגובה בפועל.6

8.3. אל תציבו סף כולל אחד

ערך קבוע כמו “כל דבר מעל 1000 Page Faults/sec הוא חריג” משנה משמעות בהתאם ל-storage, לגודל page, ל-workload ולמקומיות הגישה.

בפועל, סדרו את הבאים על אותו ציר זמן.

  • Memory\Available MBytes
  • Memory\Pages Input/sec
  • Memory\Page Reads/sec
  • Read latency / Queue בדיסק היעד
  • Working Set ו-Private Bytes של ה-process היעד
  • זמן העיבוד של האפליקציה, timeouts ותגובתיות UI

אם Available יורד באותו זמן שהעומס עולה, Pages Input/sec והמתנת דיסק עולים, וגם זמן העיבוד מחמיר, יש בסיס לחשוד ב-paging שנגרם מלחץ RAM פיזי.

9. איזה מסך או כלי לבדוק בשביל מה

מה רוצים לדעת המדד לבדוק תחילה הכלים העיקריים
הכמות ש-process היעד מחזיק כרגע ב-RAM Working Set Task Manager, Process Explorer, Get-Process
החלק הפרטי מתוך זה — RAM פרטי ל-process Private Working Set / Working Set - Private עמודות Details ב-Task Manager, Process Explorer, PerfMon
כמות ה-Commit הפרטית ל-process היעד Private Bytes / Commit Size Process Explorer, PerfMon, VMMap, Get-Process
טווח ה-virtual addresses של ה-process Virtual Bytes / Size Process Explorer, VMMap, Get-Process
מרווח ה-Commit הכולל של המערכת Committed Bytes / Commit Limit Task Manager [Performance], PerfMon
מרווח השימוש החוזר של RAM פיזי Available MBytes Task Manager, PerfMon
פירוט Standby, Modified ו-file cache page list / פירוט לפי מטרה RAMMap
מה גדל בתוך Private Bytes Heap / Private Data / Managed Heap וכו VMMap, WinDbg, dump ייעודי ל-runtime
paging שמערב דיסק Pages Input/sec, Page Reads/sec, disk latency PerfMon, WPR/WPA
בחירת כלי חקירת זיכרון של Windowsהכלי לשימוש תלוי בשאלה אם היעד הוא process אחד או כל המערכת, נקודה אחת בזמן או time series, ואם צריך לעקוב אחרי החזקה בתוך runtimeכןפירוט של נקודה אחתtime seriesכל המערכתפירוט RAM פיזיציר זמן כולל CPU, I/O והמתנותheap של .NETnative heapמה רוצים לבודדהאם היעד הוא process אחדנקודה אחת או time seriesVMMapPerfMon / PowerShellפירוט RAM פיזי או ציר זמןRAMMapWPR / WPAהאם צריך לעקוב אחרי החזקה בתוך runtimedotnet-dump / PerfViewWinDbg / Application Verifier

איור 10: החלטה תחילה על ההיקף ועל ציר הזמן מאפשרת לבחור בדיוק את הכלי שצריך, לא יותר ולא פחות.

9.1. Task Manager

ב-Task Manager, הסתכלו על המסכים בנפרד.

  • [Processes] או [Details]: משפחת Working Set ומשפחת Commit Size של processes בודדים
  • [Performance] ← [Memory]: In use, Available, Committed, Cached, Paged pool, Non-paged pool ברמת המערכת

אל תשפטו מעמודה בשם Memory לבדה — לחצו לחיצה ימנית על כותרות העמודות בלשונית [Details] והוסיפו את העמודות שצריך, כמו Working Set, Peak Working Set ו-Commit Size. שמות העמודות משתנים מעט לפי גרסת Windows ושפת התצוגה, לכן אמתו מה עמודה באמת אומרת לפני שרושמים אותה.

9.2. רישום time series עם PowerShell

אם יודעים את ה-PID של ה-process, אפשר לרשום יחד את מגמות Working Set, Private Bytes ו-Virtual Bytes עם Get-Process.

param(
    [Parameter(Mandatory)]
    [int]$ProcessId,

    [int]$IntervalSeconds = 5,
    [int]$SampleCount = 60
)

$samples = for ($i = 0; $i -lt $SampleCount; $i++) {
    $process = Get-Process -Id $ProcessId -ErrorAction Stop

    [pscustomobject]@{
        Timestamp      = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
        ProcessId      = $process.Id
        WorkingSetMB   = [math]::Round($process.WorkingSet64 / 1MB, 1)
        PrivateBytesMB = [math]::Round($process.PrivateMemorySize64 / 1MB, 1)
        VirtualBytesMB = [math]::Round($process.VirtualMemorySize64 / 1MB, 1)
        Handles        = $process.HandleCount
        Threads        = $process.Threads.Count
    }

    Start-Sleep -Seconds $IntervalSeconds
}

$samples | Format-Table -AutoSize
$samples | Export-Csv .\memory-samples.csv -NoTypeInformation -Encoding utf8

Process.WorkingSet64 של .NET מתאים ל-Working Set, PrivateMemorySize64 ל-Private Bytes, ו-VirtualMemorySize64 ל-Virtual Bytes.141516

לאפליקציה עם כמה instances, עקבו לפי PID ולא לפי שם. לניטור ארוך טווח שבו הפעלה מחדש משנה את ה-PID, תכננו את האיסוף כך שיירשם זמן ההתחלה, שם ה-service וכדומה, כדי שהיעד לעולם לא יוחלף בטעות.

9.3. לשים מערכת ו-process על אותו ציר זמן עם PerfMon

רישום לפחות של הבאים יחד מקל מאוד על הבידוד.

\Process(<יעד>)\ID Process
\Process(<יעד>)\Working Set
\Process(<יעד>)\Working Set - Private
\Process(<יעד>)\Private Bytes
\Process(<יעד>)\Virtual Bytes

\Memory\Available MBytes
\Memory\Committed Bytes
\Memory\Commit Limit
\Memory\Pages Input/sec
\Memory\Page Reads/sec
\Memory\Pool Nonpaged Bytes
\Memory\Pool Paged Bytes

כשכמה processes חולקים את אותו שם, או שמתרחשת הפעלה מחדש במהלך הניטור, שם ה-instance לבדו — Process(name) או Process(name#N) — לא יכול לנעוץ את היעד. רשמו גם ID Process לכל דגימה, ואמצו רק את ה-instance שערכו תואם ל-PID שעוקבים אחריו. כשחוצים הפעלה מחדש שמשנה את ה-PID, רשמו בנפרד גם את זמן המעבר.

שמות מוני הביצועים של Windows יכולים להיות מתורגמים בהתאם לשפת התצוגה. אם ציון השם האנגלי ישירות ב-PowerShell לא מוצא אותו, הוסיפו את המונה דרך ממשק PerfMon הגרפי, או בדקו את השמות בסביבה המקומית עם Get-Counter -ListSet *.

9.4. אל תבלבלו בין התפקידים של VMMap ושל RAMMap

  • VMMap: מפרק את ה-virtual memory ואת ה-Working Set של process אחד ל-Heap, Image, Mapped File, Private Data, Managed Heap וכדומה
  • RAMMap: מפרק את ה-RAM הפיזי של כל המערכת לפי מטרה, page list, process וקובץ

“מה גרם ל-Private Bytes של ה-process הזה לגדול” הוא עבודה ל-VMMap; “למה משמש ה-RAM שרשימת ה-processes לא מסבירה” הוא עבודה ל-RAMMap.1713

10. קריאת תסמינים מצירופי מספרים

התבנית שנצפתה ההשערה הראשונה מה לבדוק אחר כך
Working Set עולה, Private Bytes יציב גישה ראשונה ל-pages קיימים, DLL משותף, mapped file, file cache Image / Mapped File של VMMap, Pages Input/sec
Private Bytes עולה, Working Set יציב Commit פרטי גדל אבל אינו resident או עבר Trim Heap / Private Data / Managed Heap של VMMap
שניהם עולים מיד אחרי ההפעלה, ואז מתיישרים JIT, cache, pool, warmup של אתחול האם זה גדל שוב תחת אותו עומס נוסף
ה-baseline של Private Bytes עולה עם כל סבב עומס memory leak, cache בלי תקרה, או allocator שמחזיק זיכרון אחרי שחרור צילומי VMMap לפני ואחרי, heap dump
רק Working Set צונח בפתאומיות וחוזר עם פעילות ה-OS או האפליקציה עשו Trim ל-Working Set Private Bytes, Pages Input/sec, זמן תגובה
X ב-Committed X/Y מתקרב ל-Y לחץ Commit ברמת המערכת הצרכנים הגדולים של Private Bytes, Paged/Nonpaged Pool, הגדרות pagefile
Available נמוך, Pages Input/sec ו-disk latency גבוהים לחץ RAM פיזי ו-hard paging הצרכנים הגדולים של Working Set, RAMMap, מתאם עומס
שימוש ב-RAM גבוה אבל אין process גדול cache, shared pages, kernel pools, drivers, דחיסה וכו RAMMap, Pool Nonpaged/Paged Bytes
יש RAM פנוי, ובכל זאת רק אפליקציית ה-32-bit נכשלת תקרת virtual address space או fragmentation Free/Reserved של VMMap, הגדרת LAA של קובץ ההרצה
Private Bytes גבוה אבל אינו גדל בחזרה על העיבוד pool או cache שאולי מחזיק high-water mark המגבלה שלו, התנהגות שימוש חוזר, יציבות אחרי השיא

הדבר החשוב ביותר בטבלה הזו הוא לקרוא אותה בשילוב, לא מערך בודד.

11. הליך מעשי לחקירת memory leak

11.1. קבעו תחילה את תנאי השחזור ואת נקודת היציבות

“זה גדל במשך כמה ימים” לבדו אינו ניתן להשוואה.

  • כמה מ-warmup שאחרי ההפעלה לכלול
  • ממה מורכב מחזור פעולה אחד
  • כמה שניות להמתין אחרי מחזור אחד
  • כמה סבבים לוקח להגיע לתקרת ה-cache
  • האם אפשר להשתמש באותו קלט לגרסה הבריאה ולגרסה הבעייתית

החליטו את כל אלה.

11.2. רשמו את ה-process ואת המערכת יחד

לכל הפחות, שמרו את הבאים בחותמות זמן זהות.

  • Working Set של היעד
  • Private Bytes של היעד
  • Virtual Bytes של היעד
  • Committed Bytes / Commit Limit של המערכת
  • Available MBytes
  • Pages Input/sec
  • מספר handles, מספר threads
  • מספר פעולות או פריטים שעובדו

אם ה-Private Bytes של ה-process יציב בזמן ש-Commit של המערכת ממשיך לגדול, צריך להרחיב את ההיקף ל-processes אחרים, ל-kernel, ל-drivers ול-shared sections.

11.3. החליטו תחילה איזה “ממד” גדל

  • Working Set לבדו: pages resident, משותפים או שמקורם בקובץ, Trim וטעינה מחדש
  • Private Bytes: Commit פרטי ל-process
  • Virtual Bytes לבדו: Reserve, mapping, fragmentation של address space
  • System Commit לבדו: כולל processes אחרים וצד ה-kernel
  • Nonpaged Pool: צד driver/kernel
  • Handles / GDI / USER: resource leaks שאינם זיכרון

לדלג על הסדר הזה ולקפוץ ישר ללקיחת dump פירושו לקרוא הר של מידע בזמן שמכוונים לדבר הלא נכון.

11.4. עברו לפירוט

  • process native: VMMap, WinDbg, Application Verifier, מעקב heap
  • .NET: dotnet-counters, dotnet-gcdump, dotnet-dump, PerfView
  • ברמת המערכת: RAMMap, PerfMon, WPR/WPA
  • kernel pool: PoolMon, WinDbg

VMMap מציג את ה-virtual memory ה-committed של process, ואת ה-Working Set שהוקצה לכל חלק ממנו, מפורק לפי סוג. עד כמה אפשר לצמצם את הגידול ב-Private Bytes ל-Heap, Private Data, Managed Heap או Mapped File משנה מאוד את עלות החקירה שאחרי.17

11.5. אחרי תיקון, השוו את המגמה באותם תנאים

אין די בכך שערך השיא שונה לפני התיקון ואחריו. אם ערך ההתחלה שונה, ההשוואה יכולה להתהפך בקלות.

  • אותו מצב הפעלה
  • אותו קלט
  • אותו מספר פעולות
  • אותו זמן המתנה
  • אותו מרווח דגימה

— והשוו את ערך ה-baseline ואת המגמה אחרי כל מחזור. הוכחת תיקון memory leak אינה “המקסימום קטן יותר”, אלא שהגידול מתכנס עכשיו גם כשחוזרים על אותו עומס.

12. ניסוח מחדש של טעויות נפוצות

טעות נפוצה 1: הזיכרון ב-Task Manager שווה לכמות הכוללת שאפליקציה הקצתה

מה שזה באמת: בדקו איזו עמודה זו. למשפחת Working Set זו הכמות שכרגע resident ב-RAM; למשפחת Commit Size זה ה-Commit הפרטי לאותו process.

טעות נפוצה 2: Private Bytes שווה לבתים ב-pagefile

מה שזה באמת: Private Bytes הוא Commit Charge פרטי. זו כמות חשבונאית שכוללת גם pages שנמצאים כרגע ב-RAM וגם pages שיגובו ב-pagefile אם וכאשר יהיה צורך.

טעות נפוצה 3: Commit X/Y שווה לשימוש ב-pagefile / לקיבולת pagefile

מה שזה באמת: X הוא Commit Charge ברמת המערכת, ו-Y הוא Commit Limit. ה-pagefile מרחיב את Y, אבל X לא מתרגם ישירות לשימוש בדיסק.

טעות נפוצה 4: Page Faults/sec גבוה אומר שמחליפים לדיסק

מה שזה באמת: זה כולל גם soft fault. בדקו Pages Input/sec, Page Reads/sec ו-disk latency כדי לראות אם I/O לדיסק מעורב בפועל.

טעות נפוצה 5: RAM פנוי נמוך אומר שחסר זיכרון

מה שזה באמת: הסתכלו על Available, Standby, hard paging וזמן תגובה. למלא RAM ב-cache שניתן לשימוש חוזר זה נורמלי.

טעות נפוצה 6: הקטנת ה-Working Set אומרת שתוקן memory leak

מה שזה באמת: אולי רק פיניתם pages מה-RAM. בדקו אם Private Bytes ומה שמוחזק בתוך ה-heap באמת ירדו.

טעות נפוצה 7: עלייה ב-Private Bytes מאשרת memory leak

מה שזה באמת: אפשר לשפוט זאת רק אחרי שבדקתם אם זה מתכנס כשחוזרים על אותו workload, איזה סוג זיכרון גדל, והאם זה cache שניתן לשחרור.

13. סיכום

  • Memory Usage של Windows אינו מספר אחד. חשבו בנפרד על address space, Commit, residency ב-RAM ואפשרות שיתוף.
  • Working Set הוא ה-pages שנמצאים כרגע ב-RAM, כולל גם Private וגם Shared. Private Working Set הוא ה-pages הפרטיים ל-process ש-resident בתוך זה.
  • Private Bytes הוא Commit Charge פרטי ל-process; הוא אינו הכמות שנמצאת כרגע ב-RAM ואינו הכמות שנכתבה בפועל ל-pagefile.
  • Committed X/Y הוא Commit Charge / Commit Limit ברמת המערכת. ה-pagefile תומך בעיקר ב-Commit Limit, בפינוי pages שסומנו Modified וב-crash dump.
  • virtual address Reserved, page Committed, ו-page שנגעו בו בפועל ונכנס ל-Working Set הם שלבים נפרדים.
  • Page Fault הוא פעולה רגילה, ו-soft fault אינו קורא מהדיסק. גם hard fault יכולים להתרחש לא רק מ-pagefile אלא מ-EXE, DLL או mapped file.
  • memory leak מוכח לא לפי הגודל בנקודת זמן אחת, אלא לפי ערך ה-baseline והמגמה אחרי אותו עומס, יחד עם הפירוט.
  • הנתיב הבסיסי: VMMap לפירוט של process בודד, RAMMap ל-RAM פיזי ברמת המערכת, PerfMon ל-time series, וכלי dump ייעודי למה שקורה בתוך runtime.

בפעם הבאה שתשימו לב ב-Task Manager ש-“הזיכרון גדל”, התחילו בשאלה הזו.

מה שגדל הוא Working Set, Private Bytes, Virtual Bytes או System Commit?

השאלה הזו לבדה הופכת את נקודת הכניסה לחקירה למדויקת בהרבה.

מאמרים קשורים

תחומי ייעוץ קשורים

KomuraSoft LLC מטפלת בחקירות סיבת שורש שמשלבות PerfMon, VMMap, RAMMap, WinDbg וכלי אבחון של .NET לגידול זיכרון של אפליקציות Windows, להידרדרות ביצועים אחרי הפעלה ממושכת, ל-OutOfMemory ב-processes של 32-bit, ולמחסור בזיכרון שמתרחש רק בסביבת הלקוח. אנחנו לא עוצרים ב-“הזיכרון גבוה” — אנחנו מבודדים איזה אזור גדל, דרך איזו פעולה, למה, ומאין מפנים אליו או מחזיקים אותו.

מקורות

  1. Microsoft Learn, Working Set. על כך ש-Working Set של process הוא קבוצת ה-pages שכרגע resident בזיכרון פיזי, כולל shared pages; על ההבדל בין soft page fault ל-hard page fault; על Transition pages; ועל הסרת pages מה-Working Set. ↩ ↩2 ↩3 ↩4 ↩5

  2. Microsoft Learn, PROCESS_MEMORY_COUNTERS_EX2 structure. על ההגדרות של WorkingSetSize, PrivateWorkingSetSize, PrivateUsage ו-SharedCommitUsage, ועל כך שגם PagefileUsage וגם PrivateUsage מייצגים את ה-Commit Charge של ה-process. ↩ ↩2 ↩3 ↩4

  3. Microsoft Learn, Introduction to page files. על כך שה-pagefile תומך בפינוי pages שסומנו Modified, ב-crash dump של המערכת ובהרחבת System Commit Limit; על ההגדרות של System Commit Charge ו-Commit Limit; ועל אופן המדידה דרך Task Manager ומוני ביצועים. ↩ ↩2 ↩3 ↩4

  4. Microsoft Learn, Page State. על מצבי Free, Reserved ו-Committed של virtual page, ועל כך של-pages Reserved אין physical storage משויך והם אינם נגישים. ↩ ↩2

  5. Microsoft Learn, VirtualAlloc function. על ההבדל בין MEM_RESERVE ל-MEM_COMMIT; על כך ש-commit מחויב כנגד הזיכרון הכולל של המערכת וה-pagefile; ועל כך שה-page הפיזי בפועל לפעמים אינו מוקצה עד הגישה הראשונה. ↩ ↩2 ↩3

  6. Microsoft Learn, How to determine the appropriate page file size for 64-bit versions of Windows. על כך שגודל ה-pagefile תלוי בשיא Commit Charge ובדרישות crash dump; על כך ש-hard page fault קורא לא רק מ-pagefile אלא גם מ-EXE, DLL ו-memory-mapped files; ועל מוני הביצועים הקשורים. ↩ ↩2 ↩3 ↩4 ↩5 ↩6

  7. Microsoft Learn, Virtual Address Space. על כך שלכל process יש virtual address space עצמאי ו-page table משלו, ו-virtual address אינה כתובת פיזית כשלעצמה. ↩

  8. Microsoft Learn, Memory Limits for Windows and Windows Server Releases. על כך שה-user-mode virtual address space של process של 32-bit הוא בדרך כלל 2GB, והופך ל-2GB או ל-4GB ב-Windows של 64-bit בהתאם ל-IMAGE_FILE_LARGE_ADDRESS_AWARE. ↩

  9. Microsoft Learn, SetProcessWorkingSetSize function. על כך שערכי המינימום והמקסימום של Working Set אינם מבטיחים residency; על היכולת לרוקן Working Set; ועל כך שהגדרות או פעולות מופרזות יכולות להרע את ביצועי המערכת. ↩

  10. Microsoft Learn, Memory Performance Information. על ההתאמה בין מוני הביצועים של Windows, ממשקי ניהול הזיכרון ותצוגת Task Manager, כולל Working Set / Working Set - Private / Private Bytes של אובייקט Process, ו-Committed Bytes / Commit Limit של אובייקט System. ↩

  11. Microsoft Learn, MapViewOfFile function. על כך ש-FILE_MAP_COPY הופך כל page ל-copy-on-write פוטנציאלי, כך ש-Commit Charge לכל ה-view נשמר כדי להיות מגובה ב-pagefile בזמן המיפוי. ↩

  12. Microsoft Learn, Understanding Node Metrics and Properties in HPC Cluster Manager. על כך ש-Available Physical Memory מחושב כסכום רשימות Zeroed, Free ו-Standby, ועל משמעות כל אחת מ-page lists האלה. ↩

  13. Microsoft Sysinternals, RAMMap. על ניתוח שימוש הזיכרון הפיזי של Windows לפי מטרה, page list, process, עדיפות, page פיזי וקובץ. ↩ ↩2

  14. Microsoft Learn, Process.WorkingSet64 Property. על כך ש-WorkingSet64 מחזיר את ה-Working Set של ה-process בבתים, בהתאמה למונה הביצועים Working Set של אובייקט Process. ↩

  15. Microsoft Learn, Process.PrivateMemorySize64 Property. על כך ש-PrivateMemorySize64 מחזיר את הזיכרון הפרטי ל-process שאי אפשר לשתף עם processes אחרים, בהתאמה למונה הביצועים Private Bytes. ↩

  16. Microsoft Learn, Process.VirtualMemorySize64 Property. על כך ש-VirtualMemorySize64 מחזיר את כמות ה-virtual memory שהוקצתה ל-process, בהתאמה למונה הביצועים Virtual Bytes. ↩

  17. Microsoft Sysinternals, VMMap. על פירוק ה-virtual memory ה-committed של process לפי סוג, ועל הצגת הזיכרון הפיזי (Working Set) שהוקצה לכל אחד, יחד עם מפת זיכרון מפורטת. ↩ ↩2

מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.

העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.

המאמר קשור ישירות לשירותים הבאים.

שאלות נפוצות

שאלות נפוצות בפניות בנושא המאמר.

האם עמודת Memory ב-Task Manager מציגה את כל הזיכרון שהאפליקציה הקצתה?
לא. ל-Task Manager יש כמה עמודות זיכרון — משפחת Working Set, משפחת Private Working Set, Commit Size ואחרות — והמשמעות תלויה באיזה מסך ובאיזו עמודה מסתכלים. Working Set הוא ה-pages שכרגע resident ב-RAM; Private Bytes או Commit Size הוא כמות ה-Commit הפרטית של אותו process. אל תקראו עמודה אחת בשם Memory כקיבולת הכוללת שהאפליקציה הקצתה, או כגודל של memory leak.
מה ההבדל בין Working Set ל-Private Bytes?
Working Set הוא כמות ה-pages שנראים ל-process ושכרגע resident ב-RAM הפיזי, כולל pages שאפשר לשתף כמו קוד DLL ו-memory-mapped files. Private Bytes הוא כמות הזיכרון ה-committed שמשמשת באופן בלעדי את אותו process, בין אם הוא כרגע resident ב-RAM ובין אם לא. לכן השניים אף פעם לא שווים, ואף אחד מהם לא גדול יותר מהשני באופן קבוע.
האם Committed 18/32GB ב-Task Manager אומר שנכתבו 18GB ל-pagefile?
לא. הנתון משמאל הוא סך ה-Commit Charge שהמערכת כולה סופרת כרגע; מימין זו תקרת ה-Commit שהמערכת יכולה לתמוך בה. התקרה נקבעת בערך לפי RAM ועוד pagefile, אבל לא כל הסכום משמאל יושב בפועל ב-pagefile. רוב ה-pages ה-committed נמצאים ב-RAM, ולחלק מה-pages ה-committed מעולם לא הוקצה page פיזי. במקביל, pages שאפשר לטעון מחדש מקובץ המקור — כמו EXE, DLL ו-memory-mapped files — לא בהכרח מעלים את ה-Commit הפרטי באותה כמות שבה הם מעלים את ה-Working Set.
האם אפשר לקבל OutOfMemory גם כשיש RAM פנוי?
כן. allocation יכול להיכשל מסיבות שאינן RAM פיזי, כולל process של 32-bit שמכלה את ה-virtual address space, מחסור בטווח כתובות פנוי ורציף, תקרת ה-Commit של המערכת, או מגבלות ייחודיות ל-Job Object או ל-runtime. בפרט, process של 32-bit על Windows של 64-bit מוגבל בדרך כלל ל-2GB של user-mode virtual address space, אלא אם הוא Large Address Aware.
האם השבתת ה-pagefile הופכת את Windows למהיר יותר?
אי אפשר להניח את זה ככלל. השבתת pagefile מורידה את תקרת ה-Commit של המערכת, מקשה לפנות מ-RAM pages שסומנו Modified ואינם בשימוש, ומשפיעה על הגדרת ה-crash dump. את גודל ה-pagefile קובעים לפי מדידת שיא ה-Commit Charge ולפי ה-crash dump שצריך — זו לא הגדרה שכובים בלי הצדקה.
האם Page Faults/sec גבוה אומר שהמערכת קצרה בזיכרון?
אי אפשר לדעת מזה לבד. Page Fault כולל soft fault, שאפשר לפתור מ-Standby pages ב-RAM או מ-pages משותפים עם process אחר, ו-hard fault שקורא מהדיסק. במקום להסתכל על Page Faults/sec בבידוד, בדקו Pages Input/sec, Page Reads/sec, Available MBytes, disk latency וזמן עיבוד יחד על אותו ציר זמן.

פרופיל הכותב

עמוד היכרות עם כותב המאמר.

Go Komura

מנהל KomuraSoft LLC

מתמחה בפיתוח תוכנה עבור Windows, ייעוץ טכני וחקירת תקלות, בעיקר בפרויקטים עם מערכות קיימות ובאגים שקשה לשחזר.

קישורים ציבוריים

חזרה לבלוג