Skip to content

Instantly share code, notes, and snippets.

@ngot
Created July 24, 2017 10:17
Show Gist options
  • Save ngot/1c0f6019f3d2c3708322665f8df7b145 to your computer and use it in GitHub Desktop.
Save ngot/1c0f6019f3d2c3708322665f8df7b145 to your computer and use it in GitHub Desktop.
雪崩 Booom!
const compose = require('koa-compose');
const mids = [];
for (var i = 0; i < 20; i++) {
mids.push(async (context, next) => {
await next();
});
}
var fn = compose(mids);
var ctx = {};
console.time('bench');
for (var j = 0; j < 650000; j++) {
fn(ctx).then(() => {}).catch(e => console.log(e));
}
console.timeEnd('bench');
@ngot
Copy link
Author

ngot commented Jul 24, 2017

That is to say when concurrency greater than 650,000 with 20 middlewares, you will end up with Boom!

@ngot
Copy link
Author

ngot commented Jul 24, 2017

#
# Fatal error in , line 0
# API fatal error handler returned after process out of memory
#

==== C stack trace ===============================

    0   node                                0x0000000100bf1593 v8::base::debug::StackTrace::StackTrace() + 19
    1   node                                0x0000000100bee739 V8_Fatal + 233
    2   node                                0x0000000100143e48 v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) + 744
    3   node                                0x00000001005e03bb v8::internal::MarkCompactCollector::EvacuateNewSpaceVisitor::AllocateTargetObject(v8::internal::HeapObject*, v8::internal::HeapObject**) + 1019
    4   node                                0x00000001005df6be v8::internal::MarkCompactCollector::EvacuateNewSpaceVisitor::Visit(v8::internal::HeapObject*) + 318
    5   node                                0x00000001005eb8eb v8::internal::MarkCompactCollector::Evacuator::EvacuatePage(v8::internal::Page*) + 235
    6   node                                0x00000001005eb786 v8::internal::PageParallelJob<v8::internal::EvacuationJobTraits>::Task::RunInternal() + 198
    7   node                                0x0000000100b067d9 v8::platform::WorkerThread::Run() + 25
    8   node                                0x0000000100bf3187 v8::base::ThreadEntry(void*) + 87
    9   libsystem_pthread.dylib             0x00007fffbb83d93b _pthread_body + 180
    10  libsystem_pthread.dylib             0x00007fffbb83d887 _pthread_body + 0
    11  libsystem_pthread.dylib             0x00007fffbb83d08d thread_start + 13

@OpenGG
Copy link

OpenGG commented Jul 25, 2017

// test-async.js
const compose = require('koa-compose');

const mids = [];

for (var i = 0; i < 20; i++) {
  mids.push(async (context, next) => {
    context.a = 1;
    await next();
    context.a = 2;
  });
}

var fn = compose(mids);

var ctx = {};

console.time('bench');
for (var j = 0; j < 650000; j++) {
  if (j % 100 === 0) {
    console.log(j);
  }
  fn(ctx).then(
    () => { },
    e => console.log(e)
  );
}
console.timeEnd('bench');
MacBook-Pro:pwd user$ time node test-async.js
...
61600
61700

<--- Last few GCs --->

[88528:0x104800000]    52947 ms: Mark-sweep 1413.0 (1459.5) -> 1413.0 (1443.5) MB, 5203.1 / 0.0 ms  (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 5203 ms) last resort 
[88528:0x104800000]    57812 ms: Mark-sweep 1413.0 (1443.5) -> 1413.0 (1443.5) MB, 4864.4 / 0.0 ms  last resort 


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x3b4f7dda9891 <JS Object>
    0: builtin exit frame: assign(this=0x3b4f7dd841d9 <JS Function Object (SharedFunctionInfo 0x2b26f140af89)>,0x2b26f1402311 <undefined>,0x386c9ef4a219 <an Object with map 0xbff0db3e009>,0x3356d0d33cb9 <an Object with map 0xbff0db212b9>,0x386c9ef443e1 <an Object with map 0xbff0db031d1>)

    1: inspect(aka inspect) [util.js:193] [pc=0x33c41b352be3](this=0x2b26f1402311 <undefined>,obj=61800,opt...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
 5: v8::internal::Factory::NewTransitionArray(int) [/usr/local/bin/node]
 6: v8::internal::TransitionArray::Insert(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Map>, v8::internal::SimpleTransitionFlag) [/usr/local/bin/node]
 7: v8::internal::Map::CopyReplaceDescriptors(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::DescriptorArray>, v8::internal::Handle<v8::internal::LayoutDescriptor>, v8::internal::TransitionFlag, v8::internal::MaybeHandle<v8::internal::Name>, char const*, v8::internal::SimpleTransitionFlag) [/usr/local/bin/node]
 8: v8::internal::Map::CopyAddDescriptor(v8::internal::Handle<v8::internal::Map>, v8::internal::Descriptor*, v8::internal::TransitionFlag) [/usr/local/bin/node]
 9: v8::internal::Map::CopyWithField(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::FieldType>, v8::internal::PropertyAttributes, v8::internal::PropertyConstness, v8::internal::Representation, v8::internal::TransitionFlag) [/usr/local/bin/node]
10: v8::internal::Map::TransitionToDataProperty(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::PropertyConstness, v8::internal::Object::StoreFromKeyed) [/usr/local/bin/node]
11: v8::internal::LookupIterator::PrepareTransitionToDataProperty(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [/usr/local/bin/node]
12: v8::internal::Object::AddDataProperty(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::ShouldThrow, v8::internal::Object::StoreFromKeyed) [/usr/local/bin/node]
13: v8::internal::Runtime::SetObjectProperty(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::LanguageMode) [/usr/local/bin/node]
14: v8::internal::JSReceiver::SetOrCopyDataProperties(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSReceiver>, v8::internal::Handle<v8::internal::Object>, v8::internal::ScopedVector<v8::internal::Handle<v8::internal::Object> > const*, bool) [/usr/local/bin/node]
15: v8::internal::Builtin_Impl_ObjectAssign(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/usr/local/bin/node]
16: 0x33c41b18415d
Abort trap: 6

real	0m57.831s
user	0m48.969s
sys	0m15.256s
// test-promise.js
const compose = require('koa-compose');

const mids = [];

for (var i = 0; i < 20; i++) {
  mids.push((context, next) => {
    context.a = 1;
    return next()
      .then(() => {
        context.a = 2;
      });
  });
}

var fn = compose(mids);

var ctx = {};

console.time('bench');
for (var j = 0; j < 650000; j++) {
  if (j % 100 === 0) {
    console.log(j);
  }
  fn(ctx).then(
    () => { },
    e => console.log(e)
  );
}
console.timeEnd('bench');
MacBook-Pro:pwd user$ time node test-promise.js
...
307200
307300

<--- Last few GCs --->

[88729:0x105000000]    42553 ms: Mark-sweep 1408.1 (1460.0) -> 1408.1 (1443.5) MB, 3449.8 / 0.0 ms  (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 3450 ms) last resort 
[88729:0x105000000]    46234 ms: Mark-sweep 1408.1 (1443.5) -> 1408.1 (1443.5) MB, 3680.6 / 0.0 ms  last resort 


<--- JS stacktrace --->

==== JS stack trace =========================================

    2: arguments adaptor frame: 5->1
Security context: 0x3350495a9891 <JS Object>
    3: onwrite(aka onwrite) [_stream_writable.js:~406] [pc=0xb70ba4e3c38](this=0x231c2eb02311 <undefined>,stream=0x135a28094069 <a WriteStream with map 0x246e226bce29>,er=0x231c2eb02311 <undefined>)
    4: arguments adaptor frame: 1->2
    5: _writeGeneric [net.js:771] [pc=0xb70ba4d61ea](this=0x135a28094069 <a WriteStream with map 0x246e226bce29>,writev=0x23...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
 5: v8::internal::Factory::NewFixedArray(int, v8::internal::PretenureFlag) [/usr/local/bin/node]
 6: v8::internal::FullCodeGenerator::PopulateDeoptimizationData(v8::internal::Handle<v8::internal::Code>) [/usr/local/bin/node]
 7: v8::internal::FullCodeGenerator::MakeCode(v8::internal::CompilationInfo*, unsigned long) [/usr/local/bin/node]
 8: v8::internal::Compiler::EnsureDeoptimizationSupport(v8::internal::CompilationInfo*) [/usr/local/bin/node]
 9: v8::internal::HCompilationJob::PrepareJobImpl() [/usr/local/bin/node]
10: v8::internal::CompilationJob::PrepareJob() [/usr/local/bin/node]
11: v8::internal::(anonymous namespace)::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ConcurrencyMode, v8::internal::BailoutId, v8::internal::JavaScriptFrame*) [/usr/local/bin/node]
12: v8::internal::Compiler::CompileOptimized(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ConcurrencyMode) [/usr/local/bin/node]
13: v8::internal::Runtime_CompileOptimized_Concurrent(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
14: 0xb70ba30437d
Abort trap: 6

real	0m46.263s
user	0m44.017s
sys	0m10.230s

@OpenGG
Copy link

OpenGG commented Jul 25, 2017

async-await 消耗内存很厉害哇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment