diff --git a/doc/.NETMemoryPerformanceAnalysis.md b/doc/.NETMemoryPerformanceAnalysis.md index eea1f7f..b8a2ea9 100644 --- a/doc/.NETMemoryPerformanceAnalysis.md +++ b/doc/.NETMemoryPerformanceAnalysis.md @@ -73,47 +73,53 @@ When I was writing this document I intended to introduce concepts like concurren :black_medium_square:[GC fundamentals](#GC-Fundamentals) -:black_small_square:[Understanding the GC heap memory usage vs the process/machine memory usage](#Understanding-the-GC-heap-memory-usage-vs-the-processmachine-memory-usage) +- [Understanding the GC heap memory usage vs the process/machine memory usage](#Understanding-the-GC-heap-memory-usage-vs-the-processmachine-memory-usage) -- [GC heap is only one kind of memory usage in your process](#GC-heap-is-only-one-kind-of-memory-usage-in-your-process) + - [GC heap is only one kind of memory usage in your process](#GC-heap-is-only-one-kind-of-memory-usage-in-your-process) -- [GC is per process but is aware of physical memory load on the machine](#GC-is-per-process-but-is-aware-of-physical-memory-load-on-the-machine) + - [GC is per process but is aware of physical memory load on the machine](#GC-is-per-process-but-is-aware-of-physical-memory-load-on-the-machine) -:black_small_square:[Understanding how GCs are triggered](#Understanding-how-GCs-are-triggered) +- [Understanding how GCs are triggered](#Understanding-how-GCs-are-triggered) -- [GCs are triggered mostly due to allocations](#GCs-are-triggered-mostly-due-to-allocations) -- [Other factors that would trigger GCs](#Other-factors-that-would-trigger-GCs) + - [GCs are triggered mostly due to allocations](#GCs-are-triggered-mostly-due-to-allocations) -:black_small_square:[Understanding cost of allocations](#Understanding-cost-of-allocations) + - [Other factors that would trigger GCs](#Other-factors-that-would-trigger-GCs) -:black_small_square:[How to look at the GC heap size properly](#How-to-look-at-the-GC-heap-size-properly) +- [Understanding cost of allocations](#Understanding-cost-of-allocations) -- [Looking at the GC heap size wrt when GCs happen](#Looking-at-the-GC-heap-size-wrt-when-GCs-happen) -- [The allocation budget](#The-allocation-budget) -- [The effect of a generational GC](#The-effect-of-a-generational-GC) -- [Fragmentation (free objects) is part of the heap size](#Fragmentation-free-objects-is-part-of-the-heap-size) -- [GC's own bookkeeping](#GCs-own-bookkeeping) -- [When would GC throw an OOM exception?](#When-would-GC-throw-an-OOM-exception) +- [How to look at the GC heap size properly](#How-to-look-at-the-GC-heap-size-properly) -:black_small_square:[Understanding GC pauses, ie, when GCs are triggered and how long a GC lasts](#Understanding-GC-pauses-ie-when-GCs-are-triggered-and-how-long-a-GC-lasts) + - [Looking at the GC heap size wrt when GCs happen](#Looking-at-the-GC-heap-size-wrt-when-GCs-happen) -- [How long an individual GC lasts](#How-long-an-individual-GC-lasts) + - [The allocation budget](#The-allocation-budget) -- [How often GCs are triggered](#How-often-GCs-are-triggered) + - [The effect of a generational GC](#The-effect-of-a-generational-GC) -- [The one rule to remember](#The-one-rule-to-remember) + - [Fragmentation (free objects) is part of the heap size](#Fragmentation-free-objects-is-part-of-the-heap-size) -- [What makes an object survive](#What-makes-an-object-survive) + - [GC's own bookkeeping](#GCs-own-bookkeeping) - [1. The generational aspect](#1-The-generational-aspect) + - [When would GC throw an OOM exception?](#When-would-GC-throw-an-OOM-exception) - [2. User roots](#2-User-roots) +- [Understanding GC pauses, ie, when GCs are triggered and how long a GC lasts](#Understanding-GC-pauses-ie-when-GCs-are-triggered-and-how-long-a-GC-lasts) - [3. managed memory leaks](#3-managed-memory-leaks) + - [How long an individual GC lasts](#How-long-an-individual-GC-lasts) -- [“Mainline GC scenario” vs “not mainline”](#Mainline-GC-scenario-vs-not-mainline) + - [How often GCs are triggered](#How-often-GCs-are-triggered) -- [Part of the GC pause that’s not doing GC at all – thread suspension](#Part-of-the-GC-pause-thats-not-doing-GC-at-all-–-thread-suspension) + - [The one rule to remember](#The-one-rule-to-remember) + + - [What makes an object survive](#What-makes-an-object-survive) + + - [1. The generational aspect](#1-The-generational-aspect) + + - [2. User roots](#2-User-roots) + + - [3. managed memory leaks](#3-managed-memory-leaks) + + - [“Mainline GC scenario” vs “not mainline”](#Mainline-GC-scenario-vs-not-mainline) + + - [Part of the GC pause that’s not doing GC at all – thread suspension](#Part-of-the-GC-pause-thats-not-doing-GC-at-all-–-thread-suspension) **[Know when to worry](#Know-when-to-worry)** @@ -139,31 +145,36 @@ When I was writing this document I intended to introduce concepts like concurren :black_medium_square:[High % Pause time in GC](#High--Pause-time-in-GC) -:black_small_square:[Too many pauses, ie, too many GCs](#Too-many-pauses-ie-too-many-GCs) +- [Too many pauses, ie, too many GCs](#Too-many-pauses-ie-too-many-GCs) -- [Measure allocations](#Measure-allocations) + - [Measure allocations](#Measure-allocations) -- [How to see why a GC decided to collect a generation](#How-to-see-why-a-GC-decided-to-collect-a-generation) + - [How to see why a GC decided to collect a generation](#How-to-see-why-a-GC-decided-to-collect-a-generation) -:black_small_square:[Long individual pauses](#Long-individual-pauses) +- [Long individual pauses](#Long-individual-pauses) -- [First of all, do you have a managed memory leak?](#First-of-all-do-you-have-a-managed-memory-leak) + - [First of all, do you have a managed memory leak?](#First-of-all-do-you-have-a-managed-memory-leak) -- [Are the long pauses due to ephemeral GCs, full blocking GCs or BGCs?](#Are-the-long-pauses-due-to-ephemeral-GCs-full-blocking-GCs-or-BGCs) + - [Are the long pauses due to ephemeral GCs, full blocking GCs or BGCs?](#Are-the-long-pauses-due-to-ephemeral-GCs-full-blocking-GCs-or-BGCs) -- [Figuring out the amount of work for gen2 GCs](#Figuring-out-the-amount-of-work-for-gen2-GCs) + - [Figuring out the amount of work for gen2 GCs](#Figuring-out-the-amount-of-work-for-gen2-GCs) -- [Figuring out the amount of work for ephemeral GCs](#Figuring-out-the-amount-of-work-for-ephemeral-GCs) + - [Figuring out the amount of work for ephemeral GCs](#Figuring-out-the-amount-of-work-for-ephemeral-GCs) -- [Figuring out if the long GCs are due to GC work or not](#Figuring-out-if-the-long-GCs-are-due-to-GC-work-or-not) + - [Figuring out if the long GCs are due to GC work or not](#Figuring-out-if-the-long-GCs-are-due-to-GC-work-or-not) :black_medium_square:[Large GC heap size](#Large-GC-heap-size) - [Debugging OOM](#Debugging-OOM) + - [Is the Peak size too large but the After size is not?](#Is-the-Peak-size-too-large-but-the-After-size-is-not) + - [Is the After size too large?](#Is-the-After-size-too-large) + - [Are you doing mostly BGCs for gen2 GCs?](#Are-you-doing-mostly-BGCs-for-gen2-GCs) + - [Are you seeing a heap size that makes sense from GC’s POV, but still wanting to have a smaller heap?](#Are-you-seeing-a-heap-size-that-makes-sense-from-GCs-POV-but-still-wanting-to-have-a-smaller-heap) + - [Is GC using too much memory for its own bookkeeping?](#Is-GC-using-too-much-memory-for-its-own-bookkeeping) **[Definitive signs of perf problems](#definitive-signs-of-perf-problems)** diff --git a/doc/.NETMemoryPerformanceAnalysis.zh-CN.md b/doc/.NETMemoryPerformanceAnalysis.zh-CN.md index ebdeda0..e4d45ff 100644 --- a/doc/.NETMemoryPerformanceAnalysis.zh-CN.md +++ b/doc/.NETMemoryPerformanceAnalysis.zh-CN.md @@ -74,29 +74,35 @@ :black_medium_square:[GC 基础](#GC基础) -:black_small_square:[了解 GC 堆内存的使用与进程/机器内存的使用情况](#了解GC堆内存的使用与进程机器内存的使用情况) +- [了解 GC 堆内存的使用与进程/机器内存的使用情况](#了解GC堆内存的使用与进程机器内存的使用情况) -- [GC 堆只是你进程中的一种内存使用情况](#GC堆只是你进程中的一种内存使用情况) + - [GC 堆只是你进程中的一种内存使用情况](#GC堆只是你进程中的一种内存使用情况) -- [GC 是按进程进行的,但它知道机器上的物理内存负载](#GC是按进程进行的但它知道机器上的物理内存负载) + - [GC 是按进程进行的,但它知道机器上的物理内存负载](#GC是按进程进行的但它知道机器上的物理内存负载) -:black_small_square:[了解 GC 是如何被触发的](#了解GC是如何被触发的) +- [了解 GC 是如何被触发的](#了解GC是如何被触发的) -- [触发 GC 的主要原因是分配](#触发GC的主要原因是分配) -- [触发 GC 的其他因素](#触发GC的其他因素) + - [触发 GC 的主要原因是分配](#触发GC的主要原因是分配) -:black_small_square:[了解分配内存的成本](#了解分配内存的成本) + - [触发 GC 的其他因素](#触发GC的其他因素) -:black_small_square:[如何正确看待 GC 堆的大小](#如何正确看待GC堆的大小) +- [了解分配内存的成本](#了解分配内存的成本) -- [看一下 GC 堆的大小与 GC 发生的时间关系](#看一下GC堆的大小与GC发生的时间关系) -- [分配预算](#分配预算) -- [分代 GC 的影响](#分代GC的影响) -- [碎片化(自由对象)是堆大小的一部分](#碎片化自由对象是堆大小的一部分) -- [GC 自己的记账](#GC自己的记账) -- [什么时候 GC 会抛出一个OOM异常?](#什么时候GC会抛出一个OOM异常) +- [如何正确看待 GC 堆的大小](#如何正确看待GC堆的大小) -:black_small_square:[了解 GC 暂停-即何时触发 GC 以及 GC 持续多长时间)](#了解GC暂停即何时触发GC以及GC持续多长时间) + - [看一下 GC 堆的大小与 GC 发生的时间关系](#看一下GC堆的大小与GC发生的时间关系) + + - [分配预算](#分配预算) + + - [分代 GC 的影响](#分代GC的影响) + + - [碎片化(自由对象)是堆大小的一部分](#碎片化自由对象是堆大小的一部分) + + - [GC 自己的记账](#GC自己的记账) + + - [什么时候 GC 会抛出一个OOM异常?](#什么时候GC会抛出一个OOM异常) + +- [了解 GC 暂停-即何时触发 GC 以及 GC 持续多长时间)](#了解GC暂停即何时触发GC以及GC持续多长时间) - [单个 GC 的持续时间](#单个GC的持续时间) @@ -140,31 +146,36 @@ :black_medium_square:[GC 暂停时间百分比高](#GC暂停时间百分比高) -:black_small_square:[太多的停顿,即太多的 GC](#太多的停顿即太多的GC) +- [太多的停顿,即太多的 GC](#太多的停顿即太多的GC) -- [测量分配](#测量分配) + - [测量分配](#测量分配) -- [理解为什么 GC 决定收集这一代](#理解为什么GC决定收集这一代) + - [理解为什么 GC 决定收集这一代](#理解为什么GC决定收集这一代) -:black_small_square:[个别的长时间停顿](#个别的长时间停顿) +- [个别的长时间停顿](#个别的长时间停顿) -- [首先,您是否存在托管内存泄漏?](#首先您是否存在托管内存泄漏) + - [首先,您是否存在托管内存泄漏?](#首先您是否存在托管内存泄漏) -- [长时间的停顿是由于短暂的 GCs、完全阻塞的 GCs 还是 BGCs?](#长时间的停顿是由于短暂的GCs完全阻塞的GCs还是BGCs) + - [长时间的停顿是由于短暂的 GCs、完全阻塞的 GCs 还是 BGCs?](#长时间的停顿是由于短暂的GCs完全阻塞的GCs还是BGCs) -- [计算出 gen2 GC 的工作量](#计算出gen2-GC的工作量) + - [计算出 gen2 GC 的工作量](#计算出gen2-GC的工作量) -- [计算出短暂 GC 的工作量](#计算出短暂GC的工作量) + - [计算出短暂 GC 的工作量](#计算出短暂GC的工作量) -- [弄清楚长的 GC 是否是由于 GC 工作造成的](#弄清楚长的GC是否是由于GC工作造成的) + - [弄清楚长的 GC 是否是由于 GC 工作造成的](#弄清楚长的GC是否是由于GC工作造成的) :black_medium_square:[大尺寸的 GC 堆](#大尺寸的GC堆) - [调试 OOM](#调试OOM) + - [峰值尺寸太大,但 GC 后尺寸不大?](#峰值尺寸太大但GC后尺寸不大) + - [GC 后尺寸很大?](#GC后尺寸很大) + - [gen2 GC 是否主要为后台 GC?](#gen2-GC是否主要为后台GC) + - [你看到的堆的大小从 GC 的角度来看是合理的,但仍然希望有一个更小的堆?](#你看到的堆的大小从GC的角度来看是合理的但仍然希望有一个更小的堆) + - [GC 是否为自己的记账工作使用了太多的内存?](#GC是否为自己的记账工作使用了太多的内存) **[性能问题的明确迹象](#性能问题的明确迹象)**