GC takes too much time when create large buffers frequentely

130 views
Skip to first unread message

darcy

unread,
Nov 13, 2012, 5:09:50 AM11/13/12
to nod...@googlegroups.com
I created a 16MB buffer for every client request, and it's a local variable, which means will be GCed soon. When I run a benchmark, the qps was much less than expected, only hundreds per second. By the cpu profiler, I found that GC used 77% of total cpu time. With --trace_gc option, there are many lines like this:

  785292 ms: Mark-sweep 9.5 (46.0) -> 9.4 (46.0) MB, 14 ms [external memory allocation limit reached] [GC in old space requested].

I've found in node src, and it's output by Heap::AdjustAmountOfExternalAllocatedMemory(), which is called in constructor and destructor of Class Buffer. And when amount_since_last_global_gc is more than external_allocation_limit_(default 16MB), CollectAllGarbage() will be executed, which means with (16MB/buf_size) times new creation of Buffer, CollectAllGarbage() will be called once, which consume 14ms. 

external_allocation_limit_ is relative with v8-option of --max_new_space_size, but max_new_space_size is not available when v8 snapshot is used, which is default true. I rebuild node with "./configure --without-snapshot", and run server with "--max_new_space_size=819200", and the performance is improved about 3 times. Although, GC is still expensive, with 30% of total cpu time.

So, you should be careful with large buffers.

Andrew Chilton

unread,
Nov 13, 2012, 5:19:43 AM11/13/12
to nod...@googlegroups.com
On 13 November 2012 23:09, darcy <free...@gmail.com> wrote:
> So, you should be careful with large buffers.

Not just careful, but try to avoid them anyway. By streaming your info
to/from disk, to/from requests or to/from external services you'll
avoid having to use large buffers completely. It's probably a good
practice to get into, rather than allocating large amounts of memory
per request.

Cheers,
Andy

--
Andrew Chilton
e: chi...@appsattic.com
w: http://appsattic.com/
t: https://twitter.com/andychilton

darcy

unread,
Nov 13, 2012, 9:55:48 PM11/13/12
to nod...@googlegroups.com
It cannot be avoid sometimes. In my case, I need to build a new block of binary data, then send to client. Even use C++ addon to build data, it's still necessary to return a Buffer for network sending.

Chad Engler

unread,
Nov 14, 2012, 7:24:27 AM11/14/12
to nod...@googlegroups.com

Is there no way that you can stream the chunks as you read them as opposed to buffering it all in memory first?

 

-Chad

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

darcy

unread,
Nov 14, 2012, 9:04:03 PM11/14/12
to nod...@googlegroups.com
I'm not reading anything, but create some data and send to client connection.
Reply all
Reply to author
Forward
0 new messages