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

Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS #604

Open
UltimatePea opened this issue Jan 8, 2024 · 5 comments
Open

Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS #604

UltimatePea opened this issue Jan 8, 2024 · 5 comments

Comments

@UltimatePea
Copy link

Sorry if this is a dumb question. I have a program that repeatedly allocates medium sized blocks (around 2KB~2MB) consecutively for 3 minutes, and roughly all blocks are discarded seconds after allocation. The libgc runtime still prompts the error.

Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS

I manually increased those values in gc_priv.h. However, the issue still persists.

I tried both master and ubuntu distribution libgc-8.0.6 with apt source libgc-dev on ubuntu-WSL2. Here're the relevant changes and information about the built shared object.

Changes:

~/y/bdwgc (master|✚1) $ grep -rIn "define MAX_HEAP_SECTS" . ../libgc-8.0.6/
./include/private/gc_priv.h:1277:#     define MAX_HEAP_SECTS 8192000000
./include/private/gc_priv.h:1279:#     define MAX_HEAP_SECTS 7680000000
./include/private/gc_priv.h:1283:#     define MAX_HEAP_SECTS 38400000
./include/private/gc_priv.h:1285:#     define MAX_HEAP_SECTS 12800000         /* Roughly 256 MB (128*2048*1024) */
./include/private/gc_priv.h:1288:#   define MAX_HEAP_SECTS 102400000 		/* Roughly 8 GB */
./include/private/gc_priv.h:1290:#   define MAX_HEAP_SECTS 51200000           /* Roughly 4 GB */
../libgc-8.0.6/include/private/gc_priv.h:1204:#     define MAX_HEAP_SECTS 81920000
../libgc-8.0.6/include/private/gc_priv.h:1206:#     define MAX_HEAP_SECTS 76800000
../libgc-8.0.6/include/private/gc_priv.h:1210:#     define MAX_HEAP_SECTS 38400000
../libgc-8.0.6/include/private/gc_priv.h:1212:#     define MAX_HEAP_SECTS 12800000         /* Roughly 256MB (128*2048*1K)  */
../libgc-8.0.6/include/private/gc_priv.h:1215:#   define MAX_HEAP_SECTS 102400000          /* Roughly 8GB                  */
../libgc-8.0.6/include/private/gc_priv.h:1217:#   define MAX_HEAP_SECTS 51200000           /* Roughly 4GB                  */ 
~/y/bdwgc (master|✚1) $ grep -rIn "define MAXHINCR" . ../libgc-8.0.6/
./include/private/gc_priv.h:413:#   define MAXHINCR 409600
./include/private/gc_priv.h:417:#   define MAXHINCR 2048 /* Maximum heap increment, in blocks.  */
../libgc-8.0.6/include/private/gc_priv.h:383:#   define MAXHINCR 2048000 /* Maximum heap increment, in blocks              */
../libgc-8.0.6/include/private/gc_priv.h:386:#   define MAXHINCR 4096000                                                                                          

SO BSS information:

~/y/bdwgc (master|✚1) $ nm --print-size -D --size-sort -B ./.libs/libgc.so | grep B
0000000000103370 0000000000000004 B GC_dont_expand
0000000000030920 0000000000000004 B GC_dont_gc
000000000003091c 0000000000000004 B GC_dont_precollect
0000000000030910 0000000000000004 B GC_finalize_on_demand
0000000000030914 0000000000000004 B GC_find_leak
000000000010378c 0000000000000004 B GC_gcj_debug_kind
0000000000103790 0000000000000004 B GC_gcj_kind
0000000000103340 0000000000000004 B GC_no_dls
0000000000103374 0000000000000004 B GC_parallel
0000000000103788 0000000000000004 B GC_use_entire_heap
0000000000030908 0000000000000008 B GC_finalizer_notifier
0000000000103378 0000000000000008 B GC_gc_no
0000000000103358 0000000000000008 B GC_greatest_plausible_heap_addr
0000000000103350 0000000000000008 B GC_max_retries
0000000000103380 0000000000000008 B GC_non_gc_bytes
0000000000103360 0000000000000008 B GC_on_heap_resize
0000000000030928 0000000000000008 B GC_stackbottom
0000000000030940 00000000000d2a00 B GC_arrays
                                                                                                                                                                                                                                                   
~/y/bdwgc (master|✚1) $ nm --print-size -D --size-sort -B ../libgc-8.0.6/.libs/libgc.so | grep B
000000004e303fc8 0000000000000004 B GC_dont_expand
000000000003120c 0000000000000004 B GC_dont_gc
0000000000031208 0000000000000004 B GC_dont_precollect
00000000000311f0 0000000000000004 B GC_finalize_on_demand
00000000000311f4 0000000000000004 B GC_find_leak
000000004e304400 0000000000000004 B GC_gcj_debug_kind
000000004e304404 0000000000000004 B GC_gcj_kind
000000004e303da8 0000000000000004 B GC_no_dls
000000004e303fdc 0000000000000004 B GC_parallel
000000004e3043e8 0000000000000004 B GC_use_entire_heap
00000000000311e8 0000000000000008 B GC_finalizer_notifier
000000004e303fe0 0000000000000008 B GC_gc_no
000000004e303f78 0000000000000008 B GC_greatest_plausible_heap_addr
000000004e303f68 0000000000000008 B GC_max_retries
000000004e303fe8 0000000000000008 B GC_non_gc_bytes
000000004e303f88 0000000000000008 B GC_on_heap_resize
0000000000031210 0000000000000008 B GC_stackbottom
0000000000031220 000000004e2d28f0 B GC_arrays

I have also tried incrementing MAX_HEAP_SECTS but not MAXHINCR, and nothing works.

I also tried to set the enviroment variable, which fails.

~/y/bdwgc (master|✚1) $ env | grep GC
GC_MAXIMUM_HEAP_SIZE=68719476736

I greatly appreciate any suggestions on working around this issue.

@UltimatePea
Copy link
Author

I just realized this solution NixOS/hydra#549 that I did not try. I am trying it.

@ivmai
Copy link
Owner

ivmai commented Jan 8, 2024

Okay, I see you've found a workaround. But let's keep the issue open - the proper way, I think, is to remove MAX_HEAP_SECTS constant usage in bdwgc.

@ivmai
Copy link
Owner

ivmai commented Jan 8, 2024

Related issue (closed): #143

@UltimatePea
Copy link
Author

I just realized this solution NixOS/hydra#549 that I did not try. I am trying it.

This workaround actually does not work once the memory required exceeds a certain threshold (e.g. 100GB). The proper workaround is to rewrite the program to reduce the number of allocations.

@UltimatePea
Copy link
Author

UltimatePea commented Jan 9, 2024

The workaround also requires grouping allocations together to prevent fragmentation. For example, if the following allocation sequences are repeated:

[ 8 bytes, 1 Kb, 8 bytes, 1 Kb, 1 Kb, 8 bytes, 1 Kb, 1 Kb ...]

where only the 8 bytes allocation are retained and all 1Kb allocations are set for gc, then the collector will error out very easily.

This problem is actually very severe, in my case, the program crashes with only a 8 GB heap. Will continue to investigate a workaround.

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

No branches or pull requests

2 participants