## Feature #8015

### [patch] tuneable HEAP_GROWTH_FACTOR

**Description**

diff --git a/gc.c b/gc.c

index 925e496..71f509f 100644

--- a/gc.c

+++ b/gc.c

@@ -71,11 +71,13 @@

#endif

#define HEAP_MIN_SLOTS 10000

#define FREE_MIN 4096

+#define HEAP_GROWTH_FACTOR 1.8

typedef struct {

unsigned int initial_malloc_limit;

unsigned int initial_heap_min_slots;

unsigned int initial_free_min;

+ double initial_growth_factor;

#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE

int gc_stress;

#endif

@@ -85,6 +87,7 @@ static ruby_gc_params_t initial_params = {

GC_MALLOC_LIMIT,

HEAP_MIN_SLOTS,

FREE_MIN,

+ HEAP_GROWTH_FACTOR,

#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE

FALSE,

#endif

@@ -287,6 +290,7 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;

#define initial_malloc_limit initial_params.initial_malloc_limit

#define initial_heap_min_slots initial_params.initial_heap_min_slots

#define initial_free_min initial_params.initial_free_min

+#define initial_growth_factor initial_params.initial_growth_factor

#define is_lazy_sweeping(objspace) ((objspace)->heap.sweep_slots != 0)

@@ -605,7 +609,7 @@ initial_expand_heap(rb_objspace_t *objspace)

static void

set_heaps_increment(rb_objspace_t *objspace)

{

- size_t next_heaps_length = (size_t)(heaps_used * 1.8);

+ size_t next_heaps_length = (size_t)(heaps_used * initial_growth_factor);

if (next_heaps_length == heaps_used) { next_heaps_length++;

@@ -3333,7 +3337,7 @@ rb_gc_disable(void)

void

rb_gc_set_params(void)

{

- char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr;

+ char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr, *growth_factor_ptr;

if (rb_safe_level() > 0) return;

@@ -3360,6 +3364,16 @@ rb_gc_set_params(void)

}

}

- growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR");
- if (growth_factor_ptr != NULL) {
- double growth_factor_f = atof(growth_factor_ptr);
- if (RTEST(ruby_verbose))
- fprintf(stderr, "growth_factor=%f (%f)\n", growth_factor_f, initial_growth_factor);
- if (growth_factor_f > 0) {
- initial_growth_factor = growth_factor_f;
- }
- } + free_min_ptr = getenv("RUBY_FREE_MIN"); if (free_min_ptr != NULL) { int free_min_i = atoi(free_min_ptr);

**Related issues**

### Associated revisions

- gc.c: allow to tune growth of heap by environment variable RUBY_HEAP_SLOTS_GROWTH_FACTOR. patched by tmm1(Aman Gupta). [Feature #8015]

- gc.c: allow to tune growth of heap by environment variable RUBY_HEAP_SLOTS_GROWTH_FACTOR. patched by tmm1(Aman Gupta). [Feature #8015]

- gc.c: allow to tune growth of heap by environment variable RUBY_HEAP_SLOTS_GROWTH_FACTOR. patched by tmm1(Aman Gupta). [Feature #8015]

### History

#### #1 [ruby-core:53132] Updated by Motohiro KOSAKI about 3 years ago

The idea seems good.

- growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR");
- if (growth_factor_ptr != NULL) {
- double growth_factor_f = atof(growth_factor_ptr);

atof() don't have proper error check. it should be strtod().

- if (RTEST(ruby_verbose))
- fprintf(stderr, "growth_factor=%f (%f)\n", growth_factor_f, initial_growth_factor);
- if (growth_factor_f > 0) {
- initial_growth_factor = growth_factor_f;
- }

This seems don't work when growth_factor_f is less than 1.

#### #2 [ruby-core:53135] Updated by Aman Gupta about 3 years ago

Thanks for the review. How about this?

@@ -3366,10 +3535,11 @@ rb_gc_set_params(void)

growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); if (growth_factor_ptr != NULL) {

- double growth_factor_f = atof(growth_factor_ptr);
- double growth_factor_f = strtod(growth_factor_ptr, NULL); if (RTEST(ruby_verbose))
- fprintf(stderr, "growth_factor=%f (%f)\n", growth_factor_f, initial_growth_factor);
- if (growth_factor_f > 0) {
- fprintf(stderr, "heap_slots_growth_factor=%f (%f)\n",
- growth_factor_f, initial_growth_factor);
- if (growth_factor_f > 1) { initial_growth_factor = growth_factor_f; } }

#### #3 [ruby-core:53218] Updated by Aman Gupta about 3 years ago

Are there any objections to this patch?

#### #4 [ruby-core:53233] Updated by Narihiro Nakamura about 3 years ago

**Assignee**set to*Narihiro Nakamura*

I agree this patch. I'll merge it few days later, if there are no objections.

Thank you!

#### #5 [ruby-core:53312] Updated by Eric Hodel about 3 years ago

**Category**set to*core***Status**changed from*Open*to*Assigned***Target version**set to*2.1.0*

#### #6 Updated by Narihiro Nakamura about 3 years ago

**Status**changed from*Assigned*to*Closed***% Done**changed from*0*to*100*