RejectedSoftware Forums

Sign up

Pages: 1 2 3

Re: Automatic GC collection runs?

On Thursday, 6 September 2012 at 05:23:03 UTC, Nick Sabalausky
wrote:

On Thu, 06 Sep 2012 00:10:36 +0200
"Eldar Insafutdinov" e.insafutdinov@gmail.com wrote:

On Wednesday, 5 September 2012 at 21:34:21 UTC, Nick Sabalausky
wrote:

On Wed, 05 Sep 2012 23:22:03 +0200
"Eldar Insafutdinov" e.insafutdinov@gmail.com wrote:

Ok, I've done some more tests. This time I was stress
testing the server built with
DFLAGS="-version=VibeIdleCollect" . There was one
invocation of GC.collect() before the benchmark started(the
same one as in my previous post). During the stress test
GC.collect() wasn't called from that handler which is
expected as the server wasn't idling. The memory usage grew
to 380Mb. However when the benchmark finished there was GC
collection invoked, but the memory usage stayed at the same
level. This suggests there is a leak somewhere.

Or D's curse of false pointers. Did you compile it as 32-bit
or 64-bit?

32bit. Is it worth trying 64 bit?

Yes, particularly to help narrow down the cause:

If the problem persists on 64-bit then it sounds like a possible
memory leak as you suggested. But if the problem is false
pointers,
then it has a high likelihood of going away on 64-bit (since
non-pointer values will be much less likely to match 64-bit
memory
addresses).

I ran the tests on 64bit Linux and got the very same results -
memory usage goes up and up.

I just had a thought - could it be a D runtime issue? Because we
use a closure for handling incoming request, it must allocate
memory. Is there a chance that it's not being properly released?
Another possibility is memory fragmentation because there are so
many alocations of small objects happening on every request. I
wonder if a custom allocator could help here at all.

Re: Automatic GC collection runs?

Am 09.09.2012 15:57, schrieb Eldar Insafutdinov:

I ran the tests on 64bit Linux and got the very same results - memory
usage goes up and up.

I just had a thought - could it be a D runtime issue? Because we use a
closure for handling incoming request, it must allocate memory. Is there
a chance that it's not being properly released? Another possibility is
memory fragmentation because there are so many alocations of small
objects happening on every request. I wonder if a custom allocator could
help here at all.

The closure will only use heap allocations if it is a local function and
if it uses variables of the outer function. Delegates to member
functions or normal function pointers converted to a delegate should get
along without any allocation.

For almost all small allocations there is already a pool/free list
allocator in use. The code for this was written during a
profiling/tuning session and is not thoroughly debugged though. So I
suspect something in this area.

Re: Automatic GC collection runs?

Am 09.09.2012 15:57, schrieb Eldar Insafutdinov:

On Thursday, 6 September 2012 at 05:23:03 UTC, Nick Sabalausky wrote:

On Thu, 06 Sep 2012 00:10:36 +0200
"Eldar Insafutdinov" e.insafutdinov@gmail.com wrote:

On Wednesday, 5 September 2012 at 21:34:21 UTC, Nick Sabalausky
wrote:

On Wed, 05 Sep 2012 23:22:03 +0200
"Eldar Insafutdinov" e.insafutdinov@gmail.com wrote:

Ok, I've done some more tests. This time I was stress >>
testing the server built with >> DFLAGS="-version=VibeIdleCollect" .
There was one >> invocation of GC.collect() before the benchmark
started(the >> same one as in my previous post). During the stress
test >> GC.collect() wasn't called from that handler which is >>
expected as the server wasn't idling. The memory usage grew >> to
380Mb. However when the benchmark finished there was GC >> collection
invoked, but the memory usage stayed at the same >> level. This
suggests there is a leak somewhere.

Or D's curse of false pointers. Did you compile it as 32-bit > or
64-bit?

32bit. Is it worth trying 64 bit?

Yes, particularly to help narrow down the cause:

If the problem persists on 64-bit then it sounds like a possible
memory leak as you suggested. But if the problem is false pointers,
then it has a high likelihood of going away on 64-bit (since
non-pointer values will be much less likely to match 64-bit memory
addresses).

I ran the tests on 64bit Linux and got the very same results - memory
usage goes up and up.

I just had a thought - could it be a D runtime issue? Because we use a
closure for handling incoming request, it must allocate memory. Is there
a chance that it's not being properly released? Another possibility is
memory fragmentation because there are so many alocations of small
objects happening on every request. I wonder if a custom allocator could
help here at all.

There were two or three places where memory was leaking. The current
master now uses malloc/free for almost all per-request allocations
instead of the GC. Memory usage on Windows now stayed absolutely
constant for 1.000.000 requests on my machine (about 10 MB virtual and
4,7 MB ram).

I want to make the manual memory management optinal though because it
implies that no data of a HttpServerRequest must be stored outside of
the request handler function.

Re: Automatic GC collection runs?

There were two or three places where memory was leaking. The current
master now uses malloc/free for almost all per-request allocations
instead of the GC. Memory usage on Windows now stayed absolutely
constant for 1.000.000 requests on my machine (about 10 MB virtual and
4,7 MB ram).

and top says 51k virtual on Linux x64 for the benchmark app...

Re: Automatic GC collection runs?

On Mon, 10 Sep 2012 21:37:49 +0200
Sönke Ludwig sludwig@rejectedsoftware.com wrote:

There were two or three places where memory was leaking. The current
master now uses malloc/free for almost all per-request allocations
instead of the GC. Memory usage on Windows now stayed absolutely
constant for 1.000.000 requests on my machine (about 10 MB virtual and
4,7 MB ram).

Nice!

I want to make the manual memory management optinal though because it
implies that no data of a HttpServerRequest must be stored outside of
the request handler function.

What about just passing the HttpServerRequest to the request handler as
a scope param? That way people can still do whatever they want with it,
but the compiler makes sure they properly dup anything they want an
escaping reference to. By contrast, a mem-leeky "HttpServerRequest that
can escape the request handler" doesn't sound like it would be
particularly useful to anyone.

Re: Automatic GC collection runs?

On Monday, 10 September 2012 at 19:44:10 UTC, Sönke Ludwig wrote:

There were two or three places where memory was leaking. The
current
master now uses malloc/free for almost all per-request
allocations
instead of the GC. Memory usage on Windows now stayed
absolutely
constant for 1.000.000 requests on my machine (about 10 MB
virtual and
4,7 MB ram).

and top says 51k virtual on Linux x64 for the benchmark app...

I can confirm that it's fixed as well, it now shows some pretty
impressive results, which outperform haskell's webserver(which
they claim is the fastest!)

Re: Automatic GC collection runs?

Am 10.09.2012 21:54, schrieb Nick Sabalausky:

On Mon, 10 Sep 2012 21:37:49 +0200
Sönke Ludwig sludwig@rejectedsoftware.com wrote:

There were two or three places where memory was leaking. The current
master now uses malloc/free for almost all per-request allocations
instead of the GC. Memory usage on Windows now stayed absolutely
constant for 1.000.000 requests on my machine (about 10 MB virtual and
4,7 MB ram).

Nice!

I want to make the manual memory management optinal though because it
implies that no data of a HttpServerRequest must be stored outside of
the request handler function.

What about just passing the HttpServerRequest to the request handler as
a scope param? That way people can still do whatever they want with it,
but the compiler makes sure they properly dup anything they want an
escaping reference to. By contrast, a mem-leeky "HttpServerRequest that
can escape the request handler" doesn't sound like it would be
particularly useful to anyone.

The main problem is that every request handler then has to be augmented
with the scope modifier, which feels quite verbose. Also scope only
seems to have an effect on the object/variable itself and not on
anything that is contained in it, which is a real pity - might even call
it a bug. Both scope and unique could be extremely useful type traits,
but D is still lacking a bit there.

My current plan is to default to safe GC memory, which is reasonably
fast, and to provide the option to use the faster but unsafe manual
version when speed really matters. (I just tested the GC version and
its memory consumption is stable and only slightly worse with 11MB/5,8MB)

Re: Automatic GC collection runs?

On Mon, 10 Sep 2012 22:26:39 +0200
Sönke Ludwig sludwig@rejectedsoftware.com wrote:

My current plan is to default to safe GC memory, which is reasonably
fast, and to provide the option to use the faster but unsafe manual
version when speed really matters. (I just tested the GC version and
its memory consumption is stable and only slightly worse with
11MB/5,8MB)

Oh, so the memory leak is fixed in the GC version, too?

Re: Automatic GC collection runs?

Am 10.09.2012 23:03, schrieb Nick Sabalausky:

On Mon, 10 Sep 2012 22:26:39 +0200
Sönke Ludwig sludwig@rejectedsoftware.com wrote:

My current plan is to default to safe GC memory, which is reasonably
fast, and to provide the option to use the faster but unsafe manual
version when speed really matters. (I just tested the GC version and
its memory consumption is stable and only slightly worse with
11MB/5,8MB)

Oh, so the memory leak is fixed in the GC version, too?

Jep, it just holds on a bit more memory than it should because of a pool
allocator that is filled with each request - but eventually the whole
pool will get collected. I'll test a bit more and switch back to the GC
version as the default tomorrow.

Re: Automatic GC collection runs?

On Monday, 10 September 2012 at 21:18:41 UTC, Sönke Ludwig wrote:

Am 10.09.2012 23:03, schrieb Nick Sabalausky:

On Mon, 10 Sep 2012 22:26:39 +0200
Sönke Ludwig sludwig@rejectedsoftware.com wrote:

My current plan is to default to safe GC memory, which is
reasonably
fast, and to provide the option to use the faster but unsafe
manual
version when speed really matters. (I just tested the GC
version and
its memory consumption is stable and only slightly worse with
11MB/5,8MB)

Oh, so the memory leak is fixed in the GC version, too?

Jep, it just holds on a bit more memory than it should because
of a pool
allocator that is filled with each request - but eventually the
whole
pool will get collected. I'll test a bit more and switch back
to the GC
version as the default tomorrow.

With the latest commit that enables GC allocator as a default one
the server crashes immediately after startup.

Pages: 1 2 3