History of a bug

Cannot create GC thread but a lot of memory

Rédigé par gorki Aucun commentaire

Problem :

Launching a JVM I have the message : "Cannot create GC thread. Out of system resources"

  • Enough memory
  • Enough swap
  • Enough ulimit
  • Enough threads-max
  • Enough CPU

Event extend the PID limit...

Important (at the end) : debian version = 10.11

Solution :

After a hours of googling, I found :

But none of these solutions works and none was matching the number I had :

  • number of open files < ulimit -n
  • maximum process/tasks < ulimit -u

But in a thread, I found something that was working : UserTasksMax.
I'm running SystemD, I have around 10805 task running for my user.
And from : https://manpages.debian.org/stretch/systemd/logind.conf.5.en.html


Sets the maximum number of OS tasks each user may run concurrently. This controls the TasksMax= setting of the per-user slice unit, see systemd.resource-control(5) for details. If assigned the special value "infinity", no tasks limit is applied. Defaults to 33%, which equals 10813 with the kernel's defaults on the host, but might be smaller in OS containers.

For my suspect PID (a lot of files) :

  • cat /proc/21890/status | grep Thread => 1 thread
  • ls /proc/21890/task | wc
  • confirmed by the usual command : ps -eLf | grep calrisk | wc

I have around 10805 threads running for a given JVM very close to the limit.

Complete guide :


Parameters not present in all man page, it could grown up to 12288 on latest version.

To be check !



Swing application freeze

Rédigé par gorki Aucun commentaire

Problème :

J'ai une application en client lourd java qui fonctionnait bien. Depuis quelques jours, elle freeze quand j'ouvre une série de popup ce qu'elle ne faisait pas avant (ou que je n'avais pas remarqué).

Précision : je suis sous Linux, Gnome.

Solution :

J'ai désactivé les agents que j'avais en même temps, supprimer les options inutiles de la JVM, toujours rien.

La stacktrace me dit ceci :

"pool-19-thread-1" #175 prio=5 os_prio=0 tid=0x00007fe2b4055000 nid=0x5ee3 waiting for monitor entry [0x00007fe3d2efd000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at java.awt.KeyboardFocusManager.clearMostRecentFocusOwner(KeyboardFocusManager.java:1882)
        - waiting to lock <0x00000000e081d6e0> (a java.awt.Component$AWTTreeLock)
        at java.awt.Component.disable(Component.java:1526)
        at javax.swing.JComponent.disable(JComponent.java:3639)
        at java.awt.Component.enable(Component.java:1515)
        at java.awt.Component.setEnabled(Component.java:1478)
        at javax.swing.JComponent.setEnabled(JComponent.java:2680)
        at javax.swing.JComboBox.setEnabled(JComboBox.java:1391)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"SwingWorker-pool-4-thread-7" #171 daemon prio=5 os_prio=0 tid=0x00007fe33c6ff000 nid=0x5edf waiting on condition [0x00007fe3bbefb000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000fb81e808> (a java.util.concurrent.FutureTask)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429)
        at java.util.concurrent.FutureTask.get(FutureTask.java:191)
        at org.GNOME.Accessibility.AtkUtil.invokeInSwing(AtkUtil.java:68)
        at org.GNOME.Accessibility.AtkObject.hashCode(AtkObject.java:234)
        at org.GNOME.Accessibility.AtkWrapper.emitSignal(Native Method)
        at org.GNOME.Accessibility.AtkWrapper$5.propertyChange(AtkWrapper.java:545)
        at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
        at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
        at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)

Au final, ce lien j'ai trouvé ce lien et j'ai ajouté l'option Java sur la ligne de commande. Tout est OK.


Pour plus d'informations :


IE11 et cache-control rules

Rédigé par gorki Aucun commentaire

Problem :

I had a problem, nearly simple : on an angular 11 application, font was not displayed on IE11 on customer site.

After a few tests :

  • I reproduce it on my demo site
  • I do not reproduce in dev mode

Solution :

Well, I search for a while, and here is a summary.

  1. IE11 has a problem if header "Cache-Control: nostore" is set for fonts... Not easy to find but there is some reference here
  2. On my dev, it's working, after a check, I'm not setting Cache-Control: nostore
  3. On my demo site, I have this header, but I have a Nginx as a reverse proxy. Ok, that's why
  4. On customer site, I do not have control on network elements. One must add it also

I made the assumption that if I set a Cache directive, intermediate server won't modify it.

It works on my demo site. I'll check next on my customer site.

To add cache control on springboot, thanks Baeldung !

                .setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS));



Back to basics : hashcode and hashmap

Rédigé par gorki Aucun commentaire

Problem :

I'm building a Java agent to monitor objects. I track some objects and get metrics ont it. But to have less impact on memory, if objects are removed, I don't want to keep a reference to them. It could prevent the garbage collector to remove them.

Objects can be scanned multiple time for some reasons, so to keep a unique reference, I built an hashmap to track only one reference of these objects.

A hashmap with weak reference.

As stated by this article, weak reference can not be compared regarding their reference but only between WeakReference objects themselves. So I used the proposal of this article and create a WeakEqualReference object.

Adding is working well.

But after a while, I can not remove an object : I go through the map, I tried to remove an object given by the entrySet iterator : impossible.

Solution :

Well, I search for a while, and here is a summary.

In the article, hashcode used for WeakEqualReference is :

	public int hashCode() {
		T value = this.get();
		return value != null ? value.hashCode() : super.hashCode();

In fact, it gives :

  1. on the first call : the hashcode of the value
  2. on the second call, after value has been removed : the hashcode of the WeakEqualsReference

But when object is stored in the hashmap, this is the first hashcode which is used. And the hashmap never find the new hashcode after the value becomes null. Containskey, remove, all is wrong.

Hashcode must be consistent for the duration of the WeakEqualsReference.

So, my solution is to compute the hascode on the first call, when the object is stored in the hashmap, return it each times after that. WeakEqualsReference can now be removed safely.

import java.lang.ref.WeakReference;

public class WeakEqualReference<T> extends WeakReference<T> {

	private int hashCode = 0;

	public WeakEqualReference(T r) {

	public boolean equals(Object other) {

		boolean returnValue = super.equals(other);

		// If we're not equal, then check equality using referenced objects
		if (!returnValue && (other instanceof WeakEqualReference<?>)) {
			T value = this.get();
			if (null != value) {
				T otherValue = ((WeakEqualReference<T>) other).get();

				// The delegate equals should handle otherValue == null
				returnValue = value.equals(otherValue);

		return returnValue;

	public int hashCode() {
		if (hashCode == 0) {
			T value = this.get();
			hashCode = value != null ? value.hashCode() : super.hashCode();
		return hashCode;

And for the story :

- one of my values referenced was a bean with a String and another instance of WeakEqualsReference. I still had issue, but due to the String ! This string value was updated so hashcode before and after was different. Same cause, same effects.

Here the example was complicated by the WeakReference usage, but with a simple HashSet :

import java.util.HashSet;
import java.util.Objects;

public class HashCodeTest {

    public static class HashTestValue {
        public String value;

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            HashTestValue that = (HashTestValue) o;
            return Objects.equals(value, that.value);

        public int hashCode() {
            return Objects.hash(value);

    public static void main(String... args) {

        HashSet<HashTestValue> set = new HashSet();

        HashTestValue mapTestValue = new HashTestValue();
        mapTestValue.value = "1234";

        System.out.println("set.contains(mapTestValue) = " + set.contains(mapTestValue));

        mapTestValue.value = "5678";

        System.out.println("set.contains(mapTestValue) = " + set.contains(mapTestValue));


Conclusion : overriding equals and hascode is OK, but be careful of the consistency if you need to test the object after the insert !


Springboot & listening address

Rédigé par gorki Aucun commentaire

Problème :

J'ai une configuration un peu particulière :

  • je développe et teste majoritairement sous Linux, Ubuntu
  • pour certains cas, je lance une VM Windows 10 sous virtualbox pour tester IE/Edge

Je lance comme d'habitude mon application, j'essaie de m'y connecter depuis la VM impossible...

Configuration de la VM :
- en NAT
- en virtual network

Solution :

Evidemment je pense au paramètre `server.address` de Spring boot car j'ai un log qui m'affiche : Listening on
Mais ça ne marche pas...

Je tente X configurations différentes : dans le fichier de configuration, en paramètre avec le -Dserver.address

Je tente avec le port forwarding NAT de Virtualbox. Nada.

La connexion SSH fonctionne : je peux me connecter depuis la VM

Je vérifie le firewall, pas activé.

Jé vérifie IPTables, ça me semble OK

Le netstat a du mal à sortir les LISTEN, j'utilise : lsof -i -P -n | grep LISTEN

Et là :

1) Springboot écoute bien par défaut sur toutes les IPv4, comme décrit a plein d'endroit, le server.address fonctionne très bien
2) le log affiché était applicatif et codé en dur : argh :(
3) c'était le iptable qui bloquait...  il fallait regarder le FORWARD et pas le INPUT... pas sur d'avoir compris pourquoi, a priori on ne change pas de réseau/machine. A creuser. Commande iptable pour ouvrir le port.




Fil RSS des articles de cette catégorie