-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Docs: add GC user docs #58733
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
Open
IanButterworth
wants to merge
5
commits into
JuliaLang:master
Choose a base branch
from
IanButterworth:ib/gc_docs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+212
−4
Open
Docs: add GC user docs #58733
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
# [Memory Management and Garbage Collection](@id man-memory-management) | ||
|
||
Julia uses automatic memory management through its built-in garbage collector (GC). This section provides an overview of how Julia manages memory and how you can configure and optimize memory usage for your applications. | ||
|
||
## [Garbage Collection Overview](@id man-gc-overview) | ||
|
||
Julia features a garbage collector with the following characteristics: | ||
|
||
* **Non-moving**: Objects are not relocated in memory during garbage collection | ||
* **Generational**: Younger objects are collected more frequently than older ones | ||
* **Parallel and partially concurrent**: The GC can use multiple threads and run concurrently with your program | ||
* **Mostly precise**: The GC accurately identifies object references with minimal conservative scanning | ||
|
||
The garbage collector automatically reclaims memory used by objects that are no longer reachable from your program, freeing you from manual memory management in most cases. | ||
|
||
## [Memory Architecture](@id man-memory-architecture) | ||
|
||
Julia uses a two-tier allocation strategy: | ||
|
||
* **Small objects** (currently ≤ 2032 bytes but may change): Allocated using a fast per-thread pool allocator | ||
* **Large objects** : Allocated directly through the system's `malloc` | ||
|
||
This hybrid approach optimizes for both allocation speed and memory efficiency, with the pool allocator providing fast allocation for the many small objects typical in Julia programs. | ||
|
||
## [System Memory Requirements](@id man-system-memory) | ||
|
||
### Swap Space | ||
|
||
Julia's garbage collector is designed with the expectation that your system has adequate swap space configured. The GC uses heuristics that assume it can allocate memory beyond physical RAM when needed, relying on the operating system's virtual memory management. | ||
|
||
If your system has limited or no swap space, you may experience out-of-memory errors during garbage collection. In such cases, you can use the `--heap-size-hint` option to limit Julia's memory usage. | ||
|
||
### Memory Hints | ||
|
||
You can provide a hint to Julia about the maximum amount of memory to use: | ||
|
||
```bash | ||
julia --heap-size-hint=4G # To set the hint to ~4GB | ||
julia --heap-size-hint=50% # or to 50% of physical memory | ||
``` | ||
|
||
The `--heap-size-hint` option tells the garbage collector to trigger collection more aggressively when approaching the specified limit. This is particularly useful in: | ||
|
||
* Containers with memory limits | ||
* Systems without swap space | ||
* Shared systems where you want to limit Julia's memory footprint | ||
|
||
You can also set this via the `JULIA_HEAP_SIZE_HINT` environment variable: | ||
|
||
```bash | ||
export JULIA_HEAP_SIZE_HINT=2G | ||
julia | ||
``` | ||
|
||
## [Multithreaded Garbage Collection](@id man-gc-multithreading) | ||
|
||
Julia's garbage collector can leverage multiple threads to improve performance on multi-core systems. | ||
|
||
### GC Thread Configuration | ||
|
||
By default, Julia uses multiple threads for garbage collection: | ||
|
||
* **Mark threads**: Used during the mark phase to trace object references (default: 1, which is shared with the compute thread if there is only one, otherwise half the number of compute threads) | ||
* **Sweep threads**: Used for concurrent sweeping of freed memory (default: 0, disabled) | ||
|
||
You can configure GC threading using: | ||
|
||
```bash | ||
julia --gcthreads=4,1 # 4 mark threads, 1 sweep thread | ||
julia --gcthreads=8 # 8 mark threads, 0 sweep threads | ||
``` | ||
|
||
Or via environment variable: | ||
|
||
```bash | ||
export JULIA_NUM_GC_THREADS=4,1 | ||
julia | ||
``` | ||
|
||
### Recommendations | ||
|
||
For compute-intensive workloads: | ||
|
||
* Use multiple mark threads (the default configuration is usually appropriate) | ||
* Consider enabling concurrent sweeping with 1 sweep thread for allocation-heavy workloads | ||
|
||
For memory-intensive workloads: | ||
|
||
* Enable concurrent sweeping to reduce GC pauses | ||
* Monitor GC time using `@time` and adjust thread counts accordingly | ||
|
||
## [Monitoring and Debugging](@id man-gc-monitoring) | ||
|
||
### Basic Memory Monitoring | ||
|
||
Use the `@time` macro to see memory allocation and GC overhead: | ||
|
||
```julia | ||
julia> @time some_computation() | ||
2.123456 seconds (1.50 M allocations: 58.725 MiB, 17.17% gc time) | ||
``` | ||
|
||
This shows: | ||
|
||
* Total execution time | ||
* Number of allocations | ||
* Memory allocated | ||
* Percentage of time spent in garbage collection | ||
|
||
### GC Logging | ||
|
||
Enable detailed GC logging to understand collection patterns: | ||
|
||
```julia | ||
julia> GC.enable_logging(true) | ||
julia> # Run your code | ||
julia> GC.enable_logging(false) | ||
``` | ||
|
||
This logs each garbage collection event with timing and memory statistics. | ||
|
||
### Manual GC Control | ||
|
||
While generally not recommended, you can manually trigger garbage collection: | ||
|
||
```julia | ||
GC.gc() # Force a garbage collection | ||
GC.enable(false) # Disable automatic GC (use with caution!) | ||
GC.enable(true) # Re-enable automatic GC | ||
``` | ||
|
||
**Warning**: Disabling GC can lead to memory exhaustion. Only use this for specific performance measurements or debugging. | ||
|
||
## [Performance Considerations](@id man-gc-performance) | ||
|
||
### Reducing Allocations | ||
|
||
The best way to minimize GC impact is to reduce unnecessary allocations: | ||
|
||
* Use in-place operations when possible (e.g., `x .+= y` instead of `x = x + y`) | ||
* Pre-allocate arrays and reuse them | ||
* Avoid creating temporary objects in tight loops | ||
* Consider using `StaticArrays.jl` for small, fixed-size arrays | ||
|
||
### Memory-Efficient Patterns | ||
|
||
* Use `Vector{Float64}` instead of `Vector{Any}` when possible | ||
* Avoid global variables that change type | ||
* Use `const` for global constants | ||
* Consider memory pools for frequently allocated/freed objects | ||
|
||
### Profiling Memory Usage | ||
|
||
For detailed guidance on profiling memory allocations and identifying performance bottlenecks, see the [Profiling](@ref man-profiling) section. | ||
|
||
## [Advanced Configuration](@id man-gc-advanced) | ||
|
||
### Environment Variables | ||
|
||
Additional GC-related environment variables: | ||
|
||
* `JULIA_GC_WAIT_FOR_DEBUGGER`: Pause for debugger attachment during GC (debug builds only) | ||
* `JULIA_PROFILE_PEEK_HEAP_SNAPSHOT`: Enable heap snapshot collection during profiling | ||
|
||
### Integration with System Memory Management | ||
|
||
Julia works best when: | ||
|
||
* The system has adequate swap space (recommended: 2x physical RAM) | ||
* Virtual memory is properly configured | ||
* Other processes leave sufficient memory available | ||
* Container memory limits are set appropriately with `--heap-size-hint` | ||
|
||
## [Troubleshooting Memory Issues](@id man-gc-troubleshooting) | ||
|
||
### Out of Memory Errors | ||
|
||
If you encounter out-of-memory errors: | ||
|
||
1. **Check system memory**: Ensure adequate RAM and swap space | ||
2. **Use heap size hints**: Set `--heap-size-hint` to limit memory usage | ||
3. **Profile allocations**: Identify and reduce unnecessary allocations | ||
4. **Consider chunking**: Process data in smaller chunks for large datasets | ||
|
||
### High GC Overhead | ||
|
||
If garbage collection is taking too much time: | ||
|
||
1. **Reduce allocation rate**: Focus on algorithmic improvements | ||
2. **Adjust GC threads**: Experiment with different `--gcthreads` settings | ||
3. **Use concurrent sweeping**: Enable background sweeping with `--gcthreads=N,1` | ||
4. **Profile memory patterns**: Identify allocation hotspots and optimize them | ||
|
||
### Memory Leaks | ||
|
||
While Julia's GC prevents most memory leaks, issues can still occur: | ||
|
||
* **Global references**: Avoid holding references to large objects in global variables | ||
* **Closures**: Be careful with closures that capture large amounts of data | ||
* **C interop**: Ensure proper cleanup when interfacing with C libraries | ||
* **Circular references**: While handled by the GC, they can delay collection | ||
|
||
For more detailed information about Julia's garbage collector internals, see the Garbage Collection section in the Developer Documentation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.