1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* gc.c (unlink_heap_slot): fix memory leak.

free slot itself at free_heap_slot().
  Reproduce-able code is here:
  N1 = 100_000; N2 = 1_000_000
  N1.times{ary = []; N2.times{ary << ''}}
  Maybe this problem is remaining in Ruby 2.0.0.
* gc.c (unlink_heap_slot): remove not working code.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42022 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-07-17 06:24:22 +00:00
parent 79d9c8ac72
commit fa014681d5
2 changed files with 24 additions and 20 deletions

View file

@ -1,3 +1,15 @@
Wed Jul 17 15:21:10 2013 Koichi Sasada <ko1@atdot.net>
* gc.c (unlink_heap_slot): fix memory leak.
free slot itself at free_heap_slot().
Reproduce-able code is here:
N1 = 100_000; N2 = 1_000_000
N1.times{ary = []; N2.times{ary << ''}}
Maybe this problem is remaining in Ruby 2.0.0.
* gc.c (unlink_heap_slot): remove not working code.
Wed Jul 17 14:31:13 2013 Koichi Sasada <ko1@atdot.net>
* gc.c: re-design the heap structure.

32
gc.c
View file

@ -313,7 +313,6 @@ typedef struct rb_objspace {
size_t length;
size_t used;
RVALUE *range[2];
struct heap_slot_body *freed;
size_t free_num;
size_t free_min;
size_t final_num;
@ -477,7 +476,6 @@ VALUE *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
#define lomem objspace->heap.range[0]
#define himem objspace->heap.range[1]
#define heap_inc objspace->heap.increment
#define heap_freed objspace->heap.freed
#define dont_gc objspace->flags.dont_gc
#define during_gc objspace->flags.during_gc
#define finalizing objspace->flags.finalizing
@ -1208,39 +1206,33 @@ unlink_heap_slot(rb_objspace_t *objspace, struct heap_slot *slot)
slot->next = NULL;
}
static void
free_heap_slot(rb_objspace_t *objspace, struct heap_slot *slot)
{
aligned_free(slot->body);
free(slot);
}
static void
free_unused_slots(rb_objspace_t *objspace)
{
size_t i, j;
struct heap_slot_body *last = 0;
for (i = j = 1; j < heap_used; i++) {
if (objspace->heap.sorted[i]->limit == 0) {
if (!last) {
last = objspace->heap.sorted[i]->body;
}
else {
aligned_free(objspace->heap.sorted[i]->body);
}
struct heap_slot *slot = objspace->heap.sorted[i];
if (slot->limit == 0) {
free_heap_slot(objspace, slot);
heap_used--;
}
else {
if (i != j) {
objspace->heap.sorted[j] = objspace->heap.sorted[i];
objspace->heap.sorted[j] = slot;
}
j++;
}
}
if (last) {
if (last < heap_freed) {
aligned_free(heap_freed);
heap_freed = last;
}
else {
aligned_free(last);
}
}
}
static inline void
make_deferred(RVALUE *p)
{