Comparing Java and Nodejs for a low resource solution

by | November 7, 2018 | Technology

Our requirement

One of our software development customers (anonymous at the moment) is in the business of selling or renting out high scale audio and visual equipment to third party event hosts that require the equipment in order to organize large scale festivals or conferences such as the Untold festival, Tomorrowland, DEVOXX and so forth. The most representative visual equipment would be the large scale 4k display screen, which for transportation and configuration purposes is composed out of a set of inter-connectable LED panels that bind together in order to form the screen based on the required shape.

TODO

Olimex Rockchip ARM development board that should be able to run Android 4.4.2 operation system, which will host the following components:

  • A UI SPA which will allow the user to perform various operations on panels such as mapping, color calibration and so on. A Service app that will expose operations to both 3rd party clients and to the SPA
  • A low lever SDK that will expose operations for interacting with the image processing features of the processor
  • An android control monitor application, that the user will use to handle basing features as IP settings.

 

Prerequisites

The proposed environment for the ROE Nanjing project, is composed of an Olimex Rockchip ARM development board that should be able to run Android 4.4.2.

The following list covers all of the physical requirements or devices that are needed for creating the development environment

Android 4.4 Setup

Initial configuration

The configurations steps along with the required tooling for initially installing the Android 4.4.2 (KitKat) on the Olimex board can be found in the E V8-RK3188-Android.7z archive. After extracting the archive, a how-to document should be available at this path:

\EVB-RK3188-Android\RK3188-Android Update Package 20180624\docs\HOWTO – Olimex RK3188 EVB with Android.pdf

Bare-metal environment

Because we want to have a clear picture with regards to the overhead that our solution brings on top of the android environment, and also figure out it’s limitations, we’ve performed a set of bare-metal benchmarks of the runtime itself. The benchmarks were performed using Android Device Monitor (there is a more advanced Android profiles, but it required Android 5.1 in order to run)

  • Memory (~520KB of free space)

  • Storage (892MB of storage)

  • CPU Usage (3%)

What’s being tested

We want to find out the exact capabilities of the environment, so in order to do this, we would want to create multiple variants of technological stacks, that should be run on top of the existent environments, in order to see which one is the most efficient in this

low-memory/storage/computingpowerenvironment.

For the Client SPA, we’ve proposed the use of Angular 6, because we have proven it’s efficiency in other projects. As a service, we would like to test out the following stacks:

  • RESTful JBoss Undertow (Java) running in performance mode, without frameworks
  • RESTful Spring Boot microservice as aconvenient solution, with the overhead of the spring framework
  • RESTful Node.js with Express.js

The proposed test should try to figure out which one of these runtimes is faster, and more convenient for our current requirement.

For testing purposes, we’ve chosen the following basic representation of a panel. The model can get fairly complex, however, we cannot yet identify a point in the app where all of this data should be served at once, as we consider the preset section as having the most costfull HTTP calls, since a JSON will have to bear the entire representation of a system.

{

“id”:1,

“name”:”1appendedx00″, “distrobox”:”Distrobox1″, “selected”:0,

“properties”:{ “contrast”:253,

“hue”: 50,

“saturation”: 37,

“brightness”: 115,

“R”: 101,

“G”: 36,

“B”: 46

}

Issues with setting up the environment

We did not find any direct way of running Java / node.js app on top of the Android 4.4 OS. Android’s Dalvik CM does not provide a suitable runtime for Java applications, and nor could we install Node JS, since there are no node or java binaries that can work directly on top of Android.Also, suggested apps such as F-Droid,

J2ME Loader, Apogee (produced Java JREs for Android) or Java Manager seem to not be working anymore.

The found suggestions pointed out that we should try using terminal emulators, which install another OS instance on top of Android and which come bundled with a package manager, which allows for the installation of dependencies. From what we’ve found, Termux seems to be the most popular emulator, but the problem is that Termux is only supported by Android 5.1.

GNURootAndroid is a terminal emulator that also works on Android 4.4 and that allowed us to create a safe environment in order to be able to run the applications for bench-marking purposes.

 

GNURootAndroid

ATM we’ve only managed to install either JRE or node using GNURootAndroid, which practically sets up a debian instance on top of the running Android OS, that has a package manager (apt-get) and allows us to install required dependencies. There seems to be no package manager available directly on android.

After installing GNURootAndroid the system doesn’t have too much storage or memory available, as it is used by the underlying Debian that is installed by GNURootAndroid.

GNURootDebiantakesup389MBofstorageand~60MBorRAMonfirstinstall.

 

How will we measure the environment

Because our environment has to run on top of an Android OS instance, our strategy was to try and measure the footprint that our environment has on top of the OS. The tests must be platform agnostic, so bearing that in mind, we had to find a tool that would be relevant cross platform (no VisualVM or V8 profiler). As long as all the frameworks are compared with the same tool, we can establish a proportional value for performance.

  • The plan is the measure these KPIs:
  • Storage space left free after installing each environment
  • Binary storage space
  • Memory Footprint for when the environment is relaxed
  • Memory Footprint for when the environment is stressed
  • Average response time for a single request (914Kb JSON with 5k elements)
  • Average response time for a single request (retrieving data from an SQLite instance) Average response time under load (1000 requests with a concurrency of 10)
  • UI solution load time

The most convenient way for doing this would have been to use the Android Profiler which unfortunately requires Android 5.0 to run. As an alternative, we’ve tried using the good-old Android Monitor for having a visual representation of the memory. The problem with Android Monitor is that the only way we found for profiling apps was to export HPROF files and open them with the Memory Analyzer, which does not offer us a continuous stream of data.

Other alternatives implied using Android’s native procrank and dumbsys utilities in order to get successive snapshots of the system memory, which seemed suitable for what we had in mind.

UI Load time

Takes ~ 1.5 ms to load-up the UI and render 5k objects

The app took ~ 300 ms to fetch and render the initial packages having a total size of 420KB

In comparison, a more mature app that takes up 13MB of space, is fetched and server in 1.1 sec.

 

 

Java environment

Setup

  1. Install curl

apt-get install curl

  1. Install nano

apt-get install nano

  1. Install a JRE

We’ve tried installing the oracle-java-installer but it takes too much space, so we couldn’t proceed.

We’ve tried installing openjdk-8-jre-headless as a lighweigh talternative, but received SIGSEGV(0xb) when inserting data into the SQLite DB.

We’ve found out that the oracle JDK for embedded has a tool called jrecreate which allowed us to generate JRE for out up, which takes up only 59,087 KB

  1. Install nginix

curl http://nginx.org/keys/nginx_signing.key –output nginx_signing.key apt-key add nginx_signing.key

apt-get update

apt-get install nginx

Storage Footprint – 303 MB of free storage space

#GNURootDebian uses – 526 MB

#JRE uses ~60MB

#Nginx uses 50MB

#SQLite db file uses 314Kb

After installing all the dependencies required to run a our basic web server, the ARM has 303MB of free storage space.

Tools – System Panel App

We’ve installed a System Panel app for a visual representation of the data from the ARM, in real time. It’s footprint whilst running under load is:

85,929 kB: nextapp.sp (pid 1138 / activities) (for viewing)

Stack 1 – Undertow with low level operations

Response time – Single Request

It takes the undertow server ~ 5.38 sec to provide a response for the 914KB JSON from SQLite

It takes undertow server ~ 591 ms to provide a response for the 914KB JSON from a JSON file.

Memory footprint

Stress-less

The Java undertow environment takes up 49% memory in idle mode.

84153 kB: nextapp.sp (pid 1138 / activities) (for visual purposes)

13995 kB: com.gnuroot.debian (pid 1279 / activities)

38577 kB: java (pid 8913)

243 kB: nginx (pid 20226)

622 kB: nginx: worker process (pid 20228)

521 kB: nginx: worker process (pid 20229)

425 kB: nginx: worker process (pid 20230)

422 kB: nginx: worker process (pid 20231)

Total RAM occupied by apps: 54,805 KB

Free RAM: 543613 kB (35057 cached pss + 290520 cached + 218036 free)

Stressed

Whilst stressing Java, it reaches a peak of 62% memory usage.

13955 kB: com.gnuroot.debian (pid 1279 / activities)

134989 kB: java (pid 8913)

243 kB: nginx (pid 20226)

622 kB: nginx: worker process (pid 20228)

521 kB: nginx: worker process (pid 20229)

425 kB: nginx: worker process (pid 20230)

422 kB: nginx: worker process (pid 20231)

Total RAM occupied by apps (10 users): 151,177MBFree RAM: 446225 kB (35893 cached pss + 290572 cached + 119760 free)

RAM occupied by server (2 users hitting DB): 59133 kB: java (pid 8913)

 

Stack 2 – Spring backed up by Undertow

Response time – Single Request

It takes Spring ~ 2,99 sec to provide a response for the 914KB JSON from an SQLite DB.

It takes Spring ~ 475 ms to provide a response for the 914KB JSON from a JSON file.

Memory footprint

Stressless

The Java spring enviroment takes up 61% memory in idle mode

14648 kB: com.gnuroot.debian (pid 1279 / activities)

115519 kB: java (pid 9021)

251 kB: nginx (pid 20226)

538 kB: nginx: worker process (pid 20228)

538 kB: nginx: worker process (pid 20229)

491 kB: nginx: worker process (pid 20230)

491 kB: nginx: worker process (pid 20231)

Total Ram occupied by apps:132,512MB

Free RAM: 413839 kB (34855 cached pss + 343568 cached + 35416 free)

 

Stressed

Whilst stressing spring, it reaches a peak of 66% memory usage.

14460 kB: com.gnuroot.debian (pid 1279 / activities)

140999 kB: java (pid 9021)

251 kB: nginx (pid 20226)

538 kB: nginx: worker process (pid 20228)

538 kB: nginx: worker process (pid 20229)

491 kB: nginx: worker process (pid 20230)

491 kB: nginx: worker process (pid 20231)

Total Ram occupied by apps: 157,768 KB

Free RAM: 402751 kB (34675 cached pss + 332124 cached + 35952 free)

 

Node JS Environment

Setup

  1. Install curl

apt-get install curl

  1. Install nano

apt-get install nano

  1. Install NodeJs

curl -sL https://deb.nodesource.com/setup_8.x | bash – sudo apt-get install -y nodejs

  1. Install nginix

curl http://nginx.org/keys/nginx_signing.key –output nginx_signing.key apt-key add nginx_signing.key

apt-get update

apt-get install nginx

 

Storage Footprint – 238MB of free storage space

#GNURootDebian uses – 591M

#JRE uses ~60MB

#Nginx uses 50MB

#SQLite db file uses 314Kb

After installing all the dependencies required to run a our basic web server, the ARM has 238 MB of free storage space.

 

Tools – System Panel App

We’ve installed a System Panel app for a visual representation of the data from the ARM, in real time. It’s footprint whilst running under load is:

85,929 kB: nextapp.sp (pid 1138 / activities) (for viewing)

Response time – Single Request

It takes node server ~ 336 ms to provide a response for the 914KB JSON from a JSON file.

We  tried installing Sqlite but had trouble  compiling the node needed libraries for arch:

npm install sqlite3 –build-from-source –target_arch=armhf

–target_platform=linux

Memory footprint

Stress-less

The Node JS enviroment takes up 52% memory in idle mode.

13907 kB: com.gnuroot.debian (pid 5506 / activities)

32302 kB: nodejs (pid 17261)

253 kB: nginx (pid 17024)

521 kB: nginx: worker process (pid 17026)

521 kB: nginx: worker process (pid 17027)

521 kB: nginx: worker process (pid 17028)

521 kB: nginx: worker process (pid 17029)

Total RAM occupied by apps: 48,546 KB

Stressed

Whilst stressing NodeJS, it reaches a peak of  57%memory usage.

11269 kB: com.gnuroot.debian (pid 10915 / activities)

59646 kB: nodejs (pid 17261)

243 kB: nginx (pid 20226)

433 kB: nginx: worker process (pid 9786)

433 kB: nginx: worker process (pid 9787)

430 kB: nginx: worker process (pid 9788)

726 kB: nginx: worker process (pid 9785)

Total free RAM occupied by apps: 73,180 KB

Free RAM5:12882 kB (14166 cached pss + 409512 cached + 89204 free)

Conclusions

The 7zip archive contains the entire environment, covering the most relevant memory and ab test result files, binaries, runtime environments and charts.

Response time – Single Request from JSON File

Response time – 1000 requests with concurrency factor 10 (Lower is better)

Response Time – Single Request From Sqlite (Lower is better)

Memory Footprint – Relaxed (Lower is better)

Memory Footprint – Stressed (Lower is better)

Remaining storage(Higher is better)

Binaries footprint (Lower is better)

Did you find useful information in the article?

Subscribe to our newsletter to be up-to-date with our news!

We don’t like spam either

abac blog about software development projects

Subscribe To Our Newsletter

Our newsletter covers a lot of ground with regards to new and shiny tech stacks and how to use them for great efficiency.

You have Successfully Subscribed!