Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Add/RemoveMemoryPressure doc #10823

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

Maoni0
Copy link
Member

@Maoni0 Maoni0 commented Jan 9, 2025

Summary

a customer asked questions about the doc for AMP/RMP. making a fix for it.

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-runtime

Copy link

Learn Build status updates of commit 3441ec1:

✅ Validation status: passed

File Status Preview URL Details
xml/System/GC.xml ✅Succeeded View

For more details, please refer to the build report.

For any questions, please:

Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. Thanks @Maoni0

@gewarren Do you want to look and merge?

Copy link
Contributor

@gewarren gewarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Maoni0

@@ -126,13 +126,9 @@ The following example uses several GC methods to get generation and memory infor
<format type="text/markdown"><![CDATA[

## Remarks
In determining when to schedule garbage collection, the runtime takes into account how much managed memory is allocated. If a small managed object allocates a large amount of unmanaged memory, the runtime takes into account only the managed memory, and thus underestimates the urgency of scheduling garbage collection. The <xref:System.GC.AddMemoryPressure%2A> method informs the runtime of this additional pressure on system memory.
The common pattern of releasing native resources is via a finalizer on the type. If a managed object uses native memory, it could free that native memory in its finalizer. The garbage collector only knows about managed memory and schedules collections based on this knowledge. Imagine a scenario where a small managed object is associated with a large amount of native memory usage and this managed object now lives in gen2. A gen2 GC may not happen for quite some time which means this large amount of native memory will not be released till the next gen2 happens. The runtime provides the <xref:System.GC.AddMemoryPressure%2A> and <xref:System.GC.RemoveMemoryPressure%2A> methods to help with this scenario. The runtime keeps an internal record of how much these APIs added and removed, and triggers a gen2 GC if deemed productive. So this is not a feature of the GC but rather something that the runtime provides to trigger GCs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The common pattern of releasing native resources is via a finalizer on the type. If a managed object uses native memory, it could free that native memory in its finalizer. The garbage collector only knows about managed memory and schedules collections based on this knowledge. Imagine a scenario where a small managed object is associated with a large amount of native memory usage and this managed object now lives in gen2. A gen2 GC may not happen for quite some time which means this large amount of native memory will not be released till the next gen2 happens. The runtime provides the <xref:System.GC.AddMemoryPressure%2A> and <xref:System.GC.RemoveMemoryPressure%2A> methods to help with this scenario. The runtime keeps an internal record of how much these APIs added and removed, and triggers a gen2 GC if deemed productive. So this is not a feature of the GC but rather something that the runtime provides to trigger GCs.
The common pattern for releasing native resources is via a type's finalizer. If a managed object uses native memory, it can free that native memory in its finalizer. The garbage collector only knows about managed memory and schedules collections based on this knowledge. Imagine a scenario where a small managed object is associated with a large amount of native memory usage, and this managed object now lives in gen2. A gen2 GC might not happen for some time, which means the large amount of native memory won't be released until the next gen2 happens. The runtime provides the <xref:System.GC.AddMemoryPressure%2A> and <xref:System.GC.RemoveMemoryPressure%2A> methods to help with this scenario. The runtime keeps an internal record of how much memory pressure these APIs added and removed, and triggers a gen2 GC if deemed productive. So this is not a feature of the GC but rather something that the runtime provides to trigger GCs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor grammar improvements.

In the simplest usage pattern, a managed object allocates unmanaged memory in the constructor and releases it in the `Finalize` method. Call the <xref:System.GC.AddMemoryPressure%2A> method after allocating the unmanaged memory, and call the <xref:System.GC.RemoveMemoryPressure%2A> method after releasing it.

In more complicated scenarios, where the unmanaged memory allocation changes substantially during the lifetime of the managed object, you can call the <xref:System.GC.AddMemoryPressure%2A> and <xref:System.GC.RemoveMemoryPressure%2A> methods to communicate these incremental changes to the runtime.
If you have a convenient place to call these APIs, you don't necessarily have to have a finalizer. For example, when a specific method on the type is called you know you can release the native memory, you can call the <xref:System.GC.RemoveMemoryPressure%2A> method at that point instead of having a finalizer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you have a convenient place to call these APIs, you don't necessarily have to have a finalizer. For example, when a specific method on the type is called you know you can release the native memory, you can call the <xref:System.GC.RemoveMemoryPressure%2A> method at that point instead of having a finalizer.
If you have a convenient place to call these APIs, you don't necessarily have to use a finalizer. For example, if you know you can release the native memory when a specific method on the type is called, you can call the <xref:System.GC.RemoveMemoryPressure%2A> method at that point instead of having a finalizer.

The <xref:System.GC.AddMemoryPressure%2A> and <xref:System.GC.RemoveMemoryPressure%2A> methods improve performance only for types that exclusively depend on finalizers to release the unmanaged resources. It's not necessary to use these methods in types that follow the dispose pattern, where finalizers are used to clean up unmanaged resources only in the event that a consumer of the type forgets to call `Dispose`. For more information on object finalization and the dispose pattern, see [Cleaning Up Unmanaged Resources](/dotnet/standard/garbage-collection/unmanaged).

In the simplest usage pattern, a managed object allocates unmanaged memory in the constructor and releases it in the `Finalize` method. Call the <xref:System.GC.AddMemoryPressure%2A> method after allocating the unmanaged memory, and call the <xref:System.GC.RemoveMemoryPressure%2A> method after releasing it.
The common pattern of releasing native resources is via a finalizer on the type. If a managed object uses native memory, it could free that native memory in its finalizer. The garbage collector only knows about managed memory and schedules collections based on this knowledge. Imagine a scenario where a small managed object is associated with a large amount of native memory usage and this managed object now lives in gen2. A gen2 GC may not happen for quite some time which means this large amount of native memory will not be released till the next gen2 happens. The runtime provides the <xref:System.GC.AddMemoryPressure%2A> and <xref:System.GC.RemoveMemoryPressure%2A> methods to help with this scenario. The runtime keeps an internal record of how much these APIs added and removed, and triggers a gen2 GC if deemed productive. So this is not a feature of the GC but rather something that the runtime provides to trigger GCs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants