Skip to content

Memory leak when calling fs.write() in long synchronous loop #11289

@aalexgabi

Description

@aalexgabi

I think I found a memory leak when using fs.write() from a long synchronous loop. Here is the script that I used to reproduce:

var fs = require('fs')

var f = fs.openSync('/tmp/toto', 'w')
var line = 'hello\n'

for (var i = 0; i < 2000000; i++) {
  fs.write(f, line)
}

console.log('finished sync loop')

fs.fsync(f, function(){
  fs.close(f, function(){
    global.gc()
    console.log('closed')
  })
})


// Avoid script exit
setTimeout(function(){}, 600000) 

With node v0.12.9:

% node --expose-gc t4.js
finished sync loop
closed
^C
% 

After the process closed the file, there is 1.1 GB used by the process:
image

The file contains all the lines:

% wc -l toto 
2000000 toto

The file has 12 MB so I would eventually expect the node process to take around 70 MB of memory given that it takes 17 with an empty vm:

% ls -lh toto 
-rw-rw-r-- 1 alex alex 12M Feb 10 15:59 toto
% 

If I don't call the gc manually I get:
image

With node v7.5.0:

% node --expose-gc t4.js

<--- Last few GCs --->

[12644:0x2dea9c0]    50672 ms: Mark-sweep 1403.9 (1473.8) -> 1403.9 (1473.8) MB, 1299.8 / 1.1 ms  allocation failure GC in old space requested
[12644:0x2dea9c0]    51970 ms: Mark-sweep 1403.9 (1473.8) -> 1403.9 (1442.8) MB, 1297.4 / 2.2 ms  last resort gc 
[12644:0x2dea9c0]    53382 ms: Mark-sweep 1403.9 (1442.8) -> 1403.9 (1442.8) MB, 1411.4 / 1.1 ms  last resort gc 


<--- JS stacktrace --->

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

Security context: 0x27bc2abc0d39 <JS Object>
    1: write [fs.js:~669] [pc=0x2e9d77e4b286](this=0x1cdf3f4ab721 <an Object with map 0x37f0aa419701>,fd=9,buffer=0x15b7a55fff89 <String[19]\: 0.6831274126925666\n>,offset=0x27bc2ab04311 <undefined>,length=0x27bc2ab04311 <undefined>,position=0x27bc2ab04311 <undefined>,callback=0x27bc2ab04311 <undefined>)
    2: arguments adaptor frame: 2->6
    3: /* anonymous */ [/tmp/t4.js:~1] [pc=0x2e9d77e50...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [node]
 2: 0x126389c [node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
 5: v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [node]
 6: v8::internal::String::SlowFlatten(v8::internal::Handle<v8::internal::ConsString>, v8::internal::PretenureFlag) [node]
 7: v8::internal::String::Flatten(v8::internal::Handle<v8::internal::String>, v8::internal::PretenureFlag) [node]
 8: v8::String::WriteUtf8(char*, int, int*, int) const [node]
 9: node::StringBytes::Write(v8::Isolate*, char*, unsigned long, v8::Local<v8::Value>, node::encoding, int*) [node]
10: 0x1288fe9 [node]
11: 0x2e9d77e47b2f
zsh: abort (core dumped)  node --expose-gc t4.js

I have also noticed that v7.5.0 is several times slower when writing to file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    fsIssues and PRs related to the fs subsystem / file system.questionIssues that look for answers.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions