Skip to content

Latest commit

 

History

History
94 lines (64 loc) · 2.77 KB

README.md

File metadata and controls

94 lines (64 loc) · 2.77 KB

Motivation

The motivation is to better understand memory behaviour and performance with Node applications - in particular when the memory limit of the machine is reached such as on Heroku.

This allows us to experiment with the following different parameters in the make run task (see Makefile):

  • Node:

    • --max_semi_space_size
    • --max_old_space_size
    • --max_executable_size
  • Machine:

    • physical memory (Docker's --memory)
    • virtual memory (Docker's --memory-swap)

Getting Started

Docker

This uses Docker to setup a machine with memory constraints to test.

If Docker is not already setup on your computer, for the Mac using Homebrew:

brew install docker docker-machine docker-machine-driver-xhyve
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
docker-machine create --driver xhyve dev

or if you're still using the old-skool VirtualBox way:

brew cask install virtualbox
brew install docker docker-machine
docker-machine create --driver virtualbox dev

Verify that it is running:

docker-machine ls
docker-machine start dev

Setup the environment variables:

docker-machine env dev

which will detect the shell used and tell you what command to run.

Finally build the image:

make build

Running tests

make run

That will run a number of different machine configuration and Node memory settings. Some running fine, some running faster than others, and some getting killed for exceeding memory constraints.

Node version

The latest Node version is used.

You can specify a Node version to use at the top line in the Dockerfile and then build again. See Docker's list of available Node versions.

Notes

I'd pay particular attention to this comment on GitHub:

For what it's worth, here's the solution we're trying now (I sure wish I had found this conversation before!!):

if [ ! "$WEB_MEMORY" = "" ]; then
  if [ $WEB_MEMORY -le 512 ]; then
    NODE_FLAGS="--max_semi_space_size=2 --max_old_space_size=256 --max_executable_size=192"
  elif [ $WEB_MEMORY -le 768 ]; then
    NODE_FLAGS="--max_semi_space_size=8 --max_old_space_size=512 --max_executable_size=384"
  elif [ $WEB_MEMORY -le 1024 ]; then
    NODE_FLAGS="--max_semi_space_size=16 --max_old_space_size=1024 --max_executable_size=512"
  fi
fi

node $NODE_FLAGS "$@"

I'm getting the values for those flags from the V8 defaults, and it seems to be working great so far (Heroku / 512mb).