You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/website-src/docs/buffering.md
+18-6Lines changed: 18 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ This page explains how to create arrays from existing buffers without copying, h
12
12
13
13
**Predictable Layout.** Managed arrays can be moved by the garbage collector at any time. Unmanaged memory stays put, which is essential when passing pointers to native libraries or GPU drivers.
14
14
15
-
**No GC Pauses.** Large managed arrays cause GC pressure. A 1GB NDArray in unmanaged memory doesn't affect GC at all.
15
+
**Reduced GC Overhead.** Large managed arrays cause GC pressure and can trigger expensive collections. Unmanaged memory avoids this—though NumSharp still informs the GC about allocation sizes so it can schedule collections appropriately.
16
16
17
17
**Interop Efficiency.** When calling into native code (BLAS, CUDA, image processing libraries), unmanaged memory can be passed directly without marshaling.
18
18
@@ -50,6 +50,14 @@ User Code
50
50
51
51
**Internal Infrastructure** handles the low-level details: pinning managed arrays so the GC won't move them, tracking ownership so memory gets freed at the right time, and managing the raw pointers. You don't need to interact with these directly—the external APIs handle it for you.
52
52
53
+
### GC Pressure Tracking
54
+
55
+
Although NumSharp uses unmanaged memory, the .NET garbage collector still needs to know about it. Otherwise, the GC sees only the small managed wrappers (~100 bytes each) and doesn't realize there's megabytes of unmanaged data attached. This can cause memory to grow unbounded before the GC kicks in.
56
+
57
+
NumSharp solves this by calling `GC.AddMemoryPressure()` when allocating native memory and `GC.RemoveMemoryPressure()` when freeing it. This applies to arrays created with `np.array()`, `np.zeros()`, `np.empty()`, and similar functions.
58
+
59
+
For external memory (via `np.frombuffer()` with a dispose callback), the caller is responsible for pressure tracking since NumSharp doesn't know how the memory was allocated.
60
+
53
61
---
54
62
55
63
## Creating Arrays from Buffers
@@ -163,17 +171,21 @@ This is appropriate when you're borrowing memory temporarily. You must ensure th
// When arr is garbage collected, the dispose action runs
173
-
// No manual free needed
174
186
```
175
187
176
-
The `dispose` parameter takes an action that NumSharp calls when the array is no longer needed. This is cleaner for memory you've allocated, but be careful: if you free the memory yourself AND provide a dispose action, you'll double-free.
188
+
The `dispose` parameter takes an action that NumSharp calls when the array is no longer needed. For large allocations, pair `GC.AddMemoryPressure()` with `GC.RemoveMemoryPressure()` so the GC knows about your memory. Be careful: if you free the memory yourself AND provide a dispose action, you'll double-free.
0 commit comments