[#5218] Ruby Book Eng tl, ch1 question — Jon Babcock <jon@...>
From: Jon Babcock <jon@kanji.com>
Thanks.
From: Jon Babcock <jon@kanji.com>
Ah, thanks, I think I get it, a slightly different nuance then.
From: Jon Babcock <jon@kanji.com>
'Because all of Ruby has been...' -> 'Because Ruby has been...'?
[#5221] better way to say 'recursive join' — Yasushi Shoji <yashi@...>
in [ruby-dev:6289], Shugo Maeda suggested better name for recursive
[#5240] Ruby for Win32/DOS — Dennis Newbold <dennisn@...>
Not all of us are blessed with the opportunity to be able to develop on
[#5254] problem: undefined method `size' for File — "葡ic Santonacci" <Eric.Santonacci@...>
Hi all,
HI,
[#5264] Re: problem: undefined method `size' for Fil e — Aleksi Niemel<aleksi.niemela@...>
matz critizes good solution argumenting with features lacking from some
[#5268] Proper ConditionVariable usage? — Aleksi Niemel<aleksi.niemela@...>
Abstract
On Wed, 04 Oct 2000 07:05:22 +0900, Aleksi Niemelwrote:
In message <20001004110040.A26666@xs4all.nl>
Hi,
[#5276] Re: Ruby Book Eng tl, ch1 question — schneik@...
[#5294] Re: RFC: Enumerable#every(n) — Aleksi Niemel<aleksi.niemela@...>
Hastily posting something isn't good thing to do. I started to wonder if I
[#5310] Errata for Ruby Book? — Jon Babcock <jon@...>
[#5318] Redefining super method as singleton? — Robert Feldt <feldt@...>
On Fri, 6 Oct 2000, Yukihiro Matsumoto wrote:
[#5329] Ruby vs PHP ? — "Valerio Bamberga" <bamberga@...>
Hi!
[#5331] Unit testing network code? — Hugh Sasse Staff Elec Eng <hgs@...>
Can someone give me pointers on how to Unit Test code that is run on
> I think maybe one would test each end on its own first, faking the
[#5335] string streams in Ruby? — Hugh Sasse Staff Elec Eng <hgs@...>
Is there any way, without going through "modifying the internals",
[#5346] Is Ruby "enough better"? — Gabriel Lima <Gabriel.Lima@...>
Hi.
[#5364] Allowing *ary's in the middle of a camma separated list — "Akinori MUSHA" <knu@...>
Hi,
Hi,
At Tue, 10 Oct 2000 14:17:24 +0900,
[#5404] Object.foo, setters and so on — "Hal E. Fulton" <hal9000@...>
OK, here is what I think I know.
At Wed, 11 Oct 2000 11:37:25 +0900,
Hi,
Hi,
Hi,
Hi,
[#5425] Ruby Book Eng. tl, 9.8.11 -- seishitsu ? — Jon Babcock <jon@...>
At Thu, 12 Oct 2000 03:49:46 +0900,
Thanks for the input.
At Thu, 12 Oct 2000 04:53:41 +0900,
At Thu, 12 Oct 2000 07:25:03 +0900,
oops, I didn't read this one before I went out for food..
At Thu, 12 Oct 2000 09:59:19 +0900,
[#5437] Editor recommandations? — "Chris Morris" <chrismo@...>
Any recommendations on editors for Ruby script on Windows?
[#5471] 2 ideas from Haskell — Mark Slagell <ms@...>
Do either of these interest anyone:
[#5479] Some newbye question — Davide Marchignoli <marchign@...>
I am reading the documentation I found about ruby but several points
[#5480] InstallShield version for Ruby soon... — andy@... (Andrew Hunt)
Okay folks,
[#5489] Regexp#matches — Aleksi Niemel<aleksi.niemela@...>
Would someone object aliasing matches for match in Regexp?
[#5505] Sorry, What is Ruby Book — Mansuriatus Shahrir Amir <chioque@...>
Sorry if this information is somewhere obvious. I just stumbled upon
[#5516] Re: Some newbye question — ts <decoux@...>
>>>>> "D" == Davide Marchignoli <marchign@di.unipi.it> writes:
Hi,
On Sat, 14 Oct 2000, Yukihiro Matsumoto wrote:
matz@zetabits.com (Yukihiro Matsumoto) writes:
Dave Thomas <Dave@thomases.com> wrote:
Hi,
> Proposal a and b have incompatibility. I'm not sure it's worth it.
>>>>> "Y" == Yukihiro Matsumoto <matz@zetabits.com> writes:
>>>>> "Y" == Yukihiro Matsumoto <matz@zetabits.com> writes:
[#5558] GC: malloc_memories — Mathieu Bouchard <matju@...>
Hi,
> |precipitate a new GC cycle if lots of resizing is done. My biggest
[#5570] Notes about GC — Mathieu Bouchard <matju@...>
[#5600] passing single or multiple strings. — Hugh Sasse Staff Elec Eng <hgs@...>
With multple assignments I can get nested arrays "shelled" (like peas)
In message "[ruby-talk:5600] passing single or multiple strings."
[#5603] debug command list in English — "Morris, Chris" <ChrisM@...>
I found this page which lists the interactive debugger commands ... anyone
[#5619] lint? — "Swit" <swit@...>
Is there something like lint for Ruby? I'd like to find NameErrors before
[#5705] Dynamic languages, SWOT ? — Hugh Sasse Staff Elec Eng <hgs@...>
There has been discussion on this list/group from time to time about
Hugh Sasse Staff Elec Eng wrote:
On Sat, 21 Oct 2000, Charles Hixson wrote:
[#5715] Help: sockets broken — jason petrone <jp@...>
I just compiled ruby 1.6.1 on an openbsd 2.6 machine(x86).
[#5716] Re: Array#insert — Aleksi Niemel<aleksi.niemela@...>
> From: jweirich@one.net [mailto:jweirich@one.net]
[#5727] String#slice surprise — "Guy N. Hurst" <gnhurst@...>
Hi,
Dave Thomas wrote:
[#5787] Shells and Ruby — "Dat Nguyen" <thucdat@...>
Hello all,
[#5850] Re: Array#insert rehashed — Aleksi Niemel<aleksi.niemela@...>
Dave asks for:
[#5862] succ but no pred? (& the MURKY award) — "Hal E. Fulton" <hal9000@...>
First of all, a serious question:
[#5873] Integer(String) weirdness for a ruby newbie — Stoned Elipot <Stoned.Elipot@...>
Hi,
[#5881] Q:what about "Programming Ruby"? — Gabriel Lima <Gabriel.Lima@...>
Hi to you all.
[#5882] [RFC] Towards a new synchronisation primitive — hipster <hipster@...4all.nl>
Hello fellow rubyists,
On Fri, 27 Oct 2000, hipster wrote:
[#5947] Hash.new {block} / Hash#default_proc{,_set} — "Brian F. Feldman" <green@...>
I've done very little testing, but I think I've successfully implemented the
[#5959] Problem with ++? — shreeve@...2s.org (Steve Shreeve)
Here's a simple script that seems to work fine:
[ruby-talk:5917] gc.c.diff
in attachment, a diff -u patch for gc.c including: * disabled malloc_memories' effect * scale-proportionality * documentation * tuning on those values this took way too long :-( it will have to be tested with real programs. also i'd like that some people post silly programs that take advantage of the weaknesses of this version of ruby GC (seek the worst cases...) (maybe one of the first things we'll notice is that we need to reenable the malloc_memories condition again...) matju
Attachments (1)
Index: gc.c
===================================================================
RCS file: /home/cvs/ruby/gc.c,v
retrieving revision 1.41
diff -u -r1.41 gc.c
--- gc.c 2000/10/16 09:13:16 1.41
+++ gc.c 2000/10/27 14:31:16
@@ -39,16 +39,104 @@
static void run_final();
-#ifndef GC_MALLOC_LIMIT
-#if defined(MSDOS) || defined(__human68k__)
-#define GC_MALLOC_LIMIT 200000
-#else
-#define GC_MALLOC_LIMIT 8000000
-#endif
-#endif
+long gc_oalloc_live = 0;
+long gc_oalloc_recent = 0;
+long gc_malloc_recent = 0; /* unused */
+long gc_realloc_recent = 0; /* unused */
+
+void
+gc_clear_recent()
+{
+ long gc_oalloc_recent = 0;
+ long gc_malloc_recent = 0;
+ long gc_realloc_recent = 0;
+}
+
+/*!@#$ use RStruct instead to hold those constants/variables, etc. */
+
+/*******************************************************************/
+
+/*
+Garbage Collection Tuning Code and Documentation, by matju.
+
+ log for cvs:
+ added GC tuning code doc
+ GC_MALLOC_LIMIT removed
+ added three equations for tuning GC (
+
+ note: GC_MALLOC_LIMIT is no longer supported.
+
+ Garbage Collection is done when:
+ 1. when gc_oalloc_recent > gc_oalloc_threshold
+ 2. the free-list is empty
+ 3. when there is not enough free system memory (rare)
+
+ Heap activation is done when:
+ 1. after a GC phase the free-list size is too small
+
+ Heap allocation is done when:
+ 1. there are no more pre-allocated, inactive object pages.
+
+ Four counters:
+ 1. gc_oalloc_live: number of objs currently live,
+ including objects that are dead but not dealloced.
+ 2. gc_oalloc_recent: number of obj.allocs since last GC.
+ 3. gc_malloc_recent: (unused)
+ sum of malloc sizes since last GC.
+ 4. gc_realloc_recent: (unused)
+ sum of realloc target-sizes since last GC.
+
+ Three 1st degree polynomials:
+ 1. gc_oalloc_threshold: GC is run every N allocs
+ 2. gc_minimum_free_cells: when to stop activating heaps
+ 3. gc_heaps_increment: new heap allocation done in batch of N heaps
+
+ Linear equations make Ruby scale with the amount of data being processed.
+ In general you shouldn't (?) have to tune the polynomials. Exceptional
+ systems, however, should be given exceptional settings.
+
+ Even on a large machine, small process size may become important, if
+ you intend to have lots of processes.
+
+ Polynomials are of the form gc_oalloc_live * k_1n / k_1d + k_0.
+ As you see, Ruby GC scales up and down with memory usage, so that
+ the fraction of time spent on GC remains constant on average. However
+ remember that, as with most allocators/gc's, process size and number of
+ active heaps only goes up, not down, and some of the behaviour depends
+ on those values.
+*/
+
+typedef struct LinPoly {
+ long base ; /* 0th degree */
+ long slope_n; /* 1st degree: numerator */
+ long slope_d; /* 1st degree: denominator */
+} LinPoly;
+
+const LinPoly gc_oalloc_threshold = { 1024, 4, 1 };
+const LinPoly gc_minimum_free_cells = { 1024, 1, 5 };
+const LinPoly gc_heaps_increment = { 1, 1, 65536 };
-static unsigned long malloc_memories = 0;
+/* pages of 160k on an i386 */
+#define HEAP_SLOTS 8192
+static int
+linpoly_calc(self)
+ LinPoly *self;
+{
+ /* beware of overflows here */
+ return
+ gc_oalloc_live * self->slope_n / self->slope_d
+ + self->base;
+}
+
+static int
+gc_enough_allocs()
+{
+ return gc_oalloc_recent >= linpoly_calc(&gc_oalloc_threshold);
+}
+
+/*******************************************************************/
+
static void
mem_error(mesg)
char *mesg;
@@ -69,9 +157,8 @@
rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
}
if (size == 0) size = 1;
- malloc_memories += size;
-
- if (malloc_memories > GC_MALLOC_LIMIT) {
+ gc_malloc_recent += size;
+ if (gc_enough_allocs()) {
rb_gc();
}
mem = malloc(size);
@@ -80,7 +167,7 @@
mem = malloc(size);
if (!mem) {
if (size >= 10 * 1024 * 1024) {
- rb_raise(rb_eNoMemError, "tryed to allocate too big memory");
+ rb_raise(rb_eNoMemError, "tried to allocate too big memory");
}
mem_error("failed to allocate memory");
}
@@ -113,14 +200,14 @@
}
if (!ptr) return xmalloc(size);
if (size == 0) size = 1;
- malloc_memories += size;
+ gc_realloc_recent += size;
mem = realloc(ptr, size);
if (!mem) {
rb_gc();
mem = realloc(ptr, size);
if (!mem)
if (size >= 50 * 1024 * 1024) {
- rb_raise(rb_eNoMemError, "tryed to re-allocate too big memory");
+ rb_raise(rb_eNoMemError, "tried to re-allocate too big memory");
}
mem_error("failed to allocate memory(realloc)");
}
@@ -132,6 +219,9 @@
ruby_xfree(x)
void *x;
{
+ /*
+ assert(x);
+ */
if (x) free(x);
}
@@ -208,6 +298,7 @@
rb_gc_register_address(var);
}
+/* seems that on i386, sizeof(RVALUE) == 20 */
typedef struct RVALUE {
union {
struct {
@@ -235,14 +326,10 @@
static RVALUE *freelist = 0;
-#define HEAPS_INCREMENT 10
static RVALUE **heaps;
static int heaps_length = 0;
static int heaps_used = 0;
-#define HEAP_SLOTS 10000
-#define FREE_MIN 4096
-
static RVALUE *himem, *lomem;
static void
@@ -252,7 +339,7 @@
if (heaps_used == heaps_length) {
/* Realloc heaps */
- heaps_length += HEAPS_INCREMENT;
+ heaps_length += linpoly_calc(&gc_heaps_increment);
heaps = (heaps_used>0)?
(RVALUE**)realloc(heaps, heaps_length*sizeof(RVALUE*)):
(RVALUE**)malloc(heaps_length*sizeof(RVALUE*));
@@ -284,6 +371,8 @@
obj = (VALUE)freelist;
freelist = freelist->as.free.next;
MEMZERO((void*)obj, RVALUE, 1);
+ gc_oalloc_recent++;
+ gc_oalloc_live++;
return obj;
}
@@ -692,8 +781,9 @@
}
freed += n;
}
- if (freed < FREE_MIN) {
+ while (freed < linpoly_calc(&gc_minimum_free_cells)) {
add_heap();
+ freed += HEAP_SLOTS;
}
during_gc = 0;
@@ -846,6 +936,7 @@
rb_bug("gc_sweep(): unknown data type %d",
RANY(obj)->as.basic.flags & T_MASK);
}
+ gc_oalloc_live--;
}
void
@@ -914,14 +1005,15 @@
#endif
if (dont_gc || during_gc || rb_prohibit_interrupt || ruby_in_compile) {
- if (!freelist || malloc_memories > GC_MALLOC_LIMIT) {
- malloc_memories = 0;
+ /* !@#$ enough_allocs ???? */
+ if (!freelist || gc_enough_allocs()) {
+ gc_clear_recent();
add_heap();
}
return;
}
- malloc_memories = 0;
+ gc_clear_recent();
if (during_gc) return;
during_gc++;
@@ -1253,12 +1345,23 @@
return (VALUE)ptr;
}
+#define attr_reader(__a) static VALUE gc_##__a##_f() {\
+ return INT2NUM(gc_##__a);}
+
+attr_reader(oalloc_live)
+
void
Init_GC()
{
VALUE rb_mObSpace;
rb_mGC = rb_define_module("GC");
+
+#define attr_reader_def(__a) rb_define_singleton_method(\
+ rb_mGC,#__a,gc_##__a##_f, 0);
+
+ attr_reader_def(oalloc_live);
+
rb_define_singleton_method(rb_mGC, "start", gc_start, 0);
rb_define_singleton_method(rb_mGC, "enable", gc_enable, 0);
rb_define_singleton_method(rb_mGC, "disable", gc_disable, 0);
@@ -1316,3 +1419,4 @@
{
ruby_xfree(ptr);
}
+