How to Detect Memory Leaks in Java* +: Tips and Tricks

WIP

First thing: LOGS

JVM generates can generate 3 types of logs, to help you optimise the performance.

  1. GC log
  2. Thread Dump
  3. Heap Dump

Check GC algorithm

With Java 11+, G1 algorithm is the default one. For java8+ version, this new algorithm needs to be enabled explicitly.

Useful tools:

Simple way to add system variable to OSx

one simple way to add system variables to OSx is to include them in .zshrc file from your home ~

vim ~/.zshrc 

and in there the new variable and also include it into $PATH

eg: with JAVA_HOME

export JAVA_HOME="/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home"

export PATH="$JAVA_HOME:$PATH"

Gitlab Step w/ Sonar

Once with running docker images inside a continuation integration pipeline, things got to a new level.

One improvement, we can see it for static code analysis, where there is no need of having a separate instance of sonar, we can have it on the fly.

So, to have a step for this scenario, the CI pipeline, will need to:

  • lunch a Sonar instance
  • maybe add some configurations/plugins
  • run static analysis with the sonar instance
  • using Sonar API to retrieve the entire coverage

    - docker run -d --name sonarqube-$CI_BUILD_ID sonarqube

# if we want to add a plugin just copy it to the running image / eg. sonar
    - wget https://github.com/gabrie-allaigre/sonar-gitlab-plugin/releases/download/3.0.2/sonar-gitlab-plugin-3.0.2.jar
    - docker cp sonar-gitlab-plugin-3.0.2.jar sonarqube-$CI_BUILD_ID:/opt/sonarqube/extensions/plugins/sonar-gitlab-plugin-3.0.2.jar
    - docker restart sonarqube-$CI_BUILD_ID

# normal step run test & sonar analysis, giving the path to the sonar instance
    - export SONAR_IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' sonarqube-$CI_BUILD_ID`
    - ./gradlew test sonarqube -Dsonar.host.url=http://$SONAR_IP:9000

The additional scripts used by this step are the following:

generate-sonar-token.sh

#!/bin/bash
# Inspired from  https://gist.github.com/cjus/1047794

SONAR_IP=$1
PROP=$2
NAME=$3

function jsonval {
    temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $PROP`
    echo ${temp##*|}
}

json=`curl -u admin:admin -d "name=$NAME" -H "Content-Type: application/x-www-form-urlencoded" -X POST http://$SONAR_IP:9000/api/user_tokens/generate`

data=`jsonval`

echo $data

And `validate-sonar.sh` uses two scripts (maybe with time I will update them)

  • The bash scripts calls a specific python script with the coverage details retrieved from SONAR
#!/bin/bash

SONAR_TOKEN=$1

SONAR_URL=$2

sonar=$(curl -u $SONAR_TOKEN: "$2/api/measures/component?component=d2&metricKeys=coverage")

echo $sonar

exitValue=$(python ci/sonar-coverage.py $sonar 2>&1)

echo $exitValue

exit $exitValue

The python script `sonar-coverage.py` will validate if the coverage retrieved from sonar fulfills or not, the expected value of the project

import json
import sys
from decimal import Decimal

resp = json.loads(sys.argv[1])

# extract the coverage value
val = Decimal(resp['component']['measures'][0]['value'])

if val >= 80:
    print 0
else:
    print 1

When the entire step is finished, it will be nice to do some cleanup.

  after_script:
    - docker stop sonarqube-$CI_BUILD_ID
    - docker rm sonarqube-$CI_BUILD_ID

Scala Exchange 2018 – Follow UP

Interesting things discovered at Scala Exchange 2018.

Type-Driven Development in Practice: Cats and Akka HTTP

  1. creating a web service using Akka HTTP and Cats’ Free, IO, Writer and Reader monads.
  2. Presentation
  3. Code

Concurrency and Asynchrony in Scala

Featuring: Greg Dorrell

  • Scala Futures, Twitter Futures, Akka (both Actors and Streams), Monix, fs2, cats-effect. Monix & cats-effect have some very cool functions. Definitively need to be checked
  • Presentation

Cats Effect, Tagless Final & beyond!

To be continued ….