Git Product home page Git Product logo

buffer-dispose's Introduction

buffer-dispose

If this is so dangerous why should you use it? Because it can drastically increase throughput by relieving pressure from the garbage collector.

This is what's left of an attempt to allow users to manually free memory attached to a Buffer instance. It was too precarious to do in core, so now I'm making my efforts available here.


Note: This code is kept up with latest master. When v0.12 is released a 0.1 branch will be created to maintain stability.


Usage

First a note must be made that Buffer has been rewritten in Node v0.11, and SlowBuffer now has a new use. Where Buffer will automatically return a slice of data from a larger slab SlowBuffer will always allocate the exact amount requested, but SlowBuffer now returns a normal instance of Buffer instead of its own type.

For this reason the following example uses SlowBuffer. Otherwise buffer-dispose would only remove the reference to the slice it pointed to, but not free the actual memory.

var dispose = require('buffer-dispose');

var SlowBuffer = require('buffer').SlowBuffer;
var buf = new SlowBuffer(5);
console.log(buf);
dispose(buf);
console.log(buf);

// output:
// <Buffer 00 00 00 00 00>
// <Buffer >

The best use case is when receiving incoming data. Previously data returned from an incoming read() or 'data' event was allocated from an internal slab. This has been removed, and now all incoming allocations are malloc'd individually.

While this might seem to be a waste, understand that the overhead of tracking the slab along with the associated V8 calls necessary to do so, outweigh any performance benefit possibly gained.


The following is the simplest example of immediately disposing of incoming data. Remember that all incoming buffers from a connection are discretely allocated, allowing the data to be immediately free()'d.

var dispose = require('buffer-dispose');

function onData(chunk) {
  // do some quick operations on the chunk
  dispose(chunk);
}

function onConnection(socket) {
  socket.on('data', onData);
}

require('net').createServer(onConnection).listen(8000);

Though make sure all requests against the data are complete. This means you must be aware of any asynchronous events. In the following example a buffer is queued to be written to disk, but then memory is released before the asynchronous event is able to finish.

var dispose = require('buffer-dispose');
var fs = require('fs');
var buf = require('buffer').SlowBuffer(10);
buf.fill('a');

fs.writeFile('test.txt', buf, function() { });

// disposing here means nothing will be written to disk
dispose(buf);

Building

To install this from a non-globally installed build of master, use the following:

/path/to/build/node `which npm` --nodedir=/path/to/build install buffer-dispose

To build the library I do the following:

/path/to/build/node `which npm` --nodedir=/path/to/build install njsutil bindings
/path/to/build/node `which node-gyp` rebuild --nodedir=/path/to/build

Probably a better way to do this, but eh. It works for now. Submit a ticket if you have something better.

Performance Tests

To see how using this module can help your I/O I've included a performance test! It's easy to run (once you have the module built and all). Just run this:

/path/to/build/node ./speed/tcp.js <add "true" here to dispose buffers>

The below table shows performance differences cleaning up incoming Buffers at specific sizes. As we can see, the act of disposing has a performance cost. While in every case we save on memory usage, if performance is more imperative then tune your application accordingly.

64KB Writes     Throughput   Memory Usage
-----------------------------------------
Sad Ponies       26.2 Gb/s       243.2 MB
Magic Unicorns   42.5 Gb/s        47.6 MB

32KB Writes     Throughput   Memory Usage
-----------------------------------------
Sad Ponies       26.0 Gb/s       243.4 MB
Magic Unicorns   37.6 Gb/s        47.7 MB

16KB Writes     Throughput   Memory Usage
-----------------------------------------
Sad Ponies       25.3 Gb/s      243.5 MB
Magic Unicorns   26.6 Gb/s       47.6 MB

buffer-dispose's People

Contributors

trevnorris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

joaquimserafim

buffer-dispose's Issues

Node v0.10 support and API remarks

Hi Trevor,

I found this project while researching gc issues in our current project that uses lot's of buffer objects. At some point, all the garbage collections we see using --trace_gc are full mark&sweeps due to reaching v8's "external memory allocation limit".

The buffer-dispose you have here seems like a viable solution. Though I wonder whether v0.10 is affected by this just as much as v0.11?

Personally, I would vouch for something like this to make it into node core at some point. Any GC system has to make a tradeof at some point between consistency and performance. In this case, calling free on a buffer remains entirely optional and an optimization.

e.g. .NET gives you the IDisposable pattern to early-release native resources that would else require expensive finalization during garbage collection. This is a similar scenario. Nothing bad happens if you don't free a buffer but if you want more performance you can dispose it. In any case, a disposed buffer should throw exceptions anytime it's beeing accessed (in .NET disposed objects throw ObjectDisposedException), and you need to be careful about disposing elements at the right time (e.g. when working with async callbacks like in node). With a node.js buffer, the native resource is the external memory held.

So, from my point of view, this is nothing out of the ordinary and "dangerous" stuff, it's one of the core things a GC'd platform needs to provide to its developers to allow writing performant code. At it's current state, the buffer handling and gc characteristics make node.js unusable for us (long gc pauses, soft realtime requirements, loads of buffer handling and weak/embedded hardware)

Regards,
Johannes

Cannot install with the latest version of node

npm WARN package.json [email protected] No repository field.
npm http GET https://registry.npmjs.org/buffer-dispose
npm http 200 https://registry.npmjs.org/buffer-dispose
npm ERR! notarget No compatible version found: buffer-dispose@'*'
npm ERR! notarget No valid targets found.
npm ERR! notarget Perhaps not compatible with your version of node?
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

npm ERR! System Windows_NT 6.2.9200

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.