[SOLVED] Blocked threads freezing the app

Hi,

My app hangs from time to time. This is what I’ve been able to see in jconsole on my Macbook (Java6):


Name: LWJGL Renderer Thread
State: BLOCKED on java.util.concurrent.atomic.AtomicBoolean@405c9cef owned by: jME3 Audio Thread
Total blocked: 20 Total waited: 1

Stack trace:
com.jme3.audio.lwjgl.LwjglAudioRenderer.playSourceInstance(LwjglAudioRenderer.java:818)
com.jme3.audio.AudioNode.playInstance(AudioNode.java:198)
nu.zoom.jme.mj.gameplay.Raindrop.startDying(Raindrop.java:196)


Name: jME3 Audio Thread
State: RUNNABLE
Total blocked: 30 Total waited: 114,591

Stack trace:
de.jarnbjo.vorbis.VorbisStream.getNextAudioPacket(VorbisStream.java:170)
de.jarnbjo.vorbis.VorbisStream.readPcm(VorbisStream.java:140)
- locked java.lang.Object@6181ce72
com.jme3.audio.plugins.OGGLoader$JOggInputStream.read(OGGLoader.java:95)
com.jme3.audio.AudioStream.readSamples(AudioStream.java:94)


The code where I call playInstance looks like this:


[java]
final AudioNode sound;
int soundNumber = FastMath.rand.nextInt(3);
switch (soundNumber) {
case 0:
sound = new AudioNode(assetManager, "Sounds/DRIP005.wav");
break;
case 1:
sound = new AudioNode(assetManager, "Sounds/DRIP007.wav");
break;
default:
sound = new AudioNode(assetManager, "Sounds/DRIP008.wav");
}
this.raindropNode.attachChild(sound);
sound.setPositional(true);
sound.playInstance();[/java]

the "raindropNode" also holds the visible geometry. This sound is set playing a few seconds before I detach the raindropNode from the scene (it's like a dying sound) and null all references to this. The heap does not seem to keep growing so I hope that it is GC'd properly.

Question: Is this something I do wrong? Is there some clean-up that I must do that is special to the audioNodes?

EDIT: It looks to have been something in the file that caused the OGG-decoder to get stuck.

Still lots of nodes, according to the log. Also I’m no audio expert but I think sounds are buffers, and those aren’t stored on the heap. I would guess there is a leak.



Not sure what the reason is tho, it may be simple. Someone ought to know.

You can turn on detailed GC logging. I suspect that your pauses might coincide with a full GC sweep.



Though I also wonder which version of JME you are running. Is it up to date with the latest stable updates?

Doh! Forgot to add the other piece of the puzzle. The ogg-playing is the ambient background sounds. Meybe I do a no-no there. Here is the code, the method playAmbientWeather is called in each update of my AppState.





[java]public class AudioHolder {



private final Node rootNode;

private final AssetManager assetManager;

private AudioNode ambientWeather = null;

private final Logger log = Logger.getLogger(getClass().getName()) ;



public AudioHolder(Node rootNode, AssetManager assetManager) {

this.rootNode = rootNode;

this.assetManager = assetManager;

}



public void playAmbientWeather() {

if (ambientWeather == null) {

ambientWeather = new AudioNode(assetManager, "/Sounds/ambient.ogg", true, true);

ambientWeather.setVolume(2);

rootNode.attachChild(ambientWeather);

ambientWeather.play();

log.fine("Starting ambient weather playback");

}

if (ambientWeather.getStatus() == AudioNode.Status.Stopped) {

log.fine("Ambient weather playback has stopped, throwing the node away");

ambientWeather = null ;

}

}

}

[/java]

How many raindrop nodes are there? Seems like there are a whole lot of audio nodes.

@androlo said:
How many raindrop nodes are there? Seems like there are a whole lot of audio nodes.


I'm not trying to simulate rain by playing each drop separately :) It looks like this

http://www.zoom.nu/microbejump/images/screenshot.png

I don't have exact number of raindrop nodes in the scene at this particular instant but they are capped at 220 total in the scene. So no more than that. The sound is only played when the raindrop nodes hit the ground so It sounds like I designed it, that is 1 or 2 of those (shorter sounds) playing at the same time as the ambient sound.

But since something blocks the LWJGL Thread I guess I'm loosing track of nodes somewhere or maybe the streaming OGG loading is having difficulties. I'll try to isolate it this evening.

Thanks for having a look.

When you say “hang” you mean complete freeze/deadlock or just for a short time?

If its a full deadlock, then from what you said it seems that the OGG decoder somehow gets stuck in an infinite loop in the method getNextAudioPacket(), which means the audio thread is no longer accessible at that point.

@Momoko_Fan said:
When you say "hang" you mean complete freeze/deadlock or just for a short time?
If its a full deadlock, then from what you said it seems that the OGG decoder somehow gets stuck in an infinite loop in the method getNextAudioPacket(), which means the audio thread is no longer accessible at that point.


Complete deadlock as in the LJWGL Thread is blocked so the app is totally unresponsive and never snaps out of it (killed it after 25 minutes). However in jconsole I can see the other threads running, the GC is collecting memory as per usual intervalls. Memory peaks around 80 Mb and then gets collected so it looks normal except that is unresponsive.

I also had the thought that the ogg-decoder got stuck, recoded the sound into wav using VLC and now it seems to work.

Lessons learned: I got reminded that jconsole is a really good tool. Next thing I'll do is to try to hack an appstate that exposes the StatView metrics through JMX :)
@jmaasing said:
Complete deadlock as in the LJWGL Thread is blocked so the app is totally unresponsive and never snaps out of it (killed it after 25 minutes). However in jconsole I can see the other threads running, the GC is collecting memory as per usual intervalls. Memory peaks around 80 Mb and then gets collected so it looks normal except that is unresponsive.

I also had the thought that the ogg-decoder got stuck, recoded the sound into wav using VLC and now it seems to work.

Lessons learned: I got reminded that jconsole is a really good tool. Next thing I'll do is to try to hack an appstate that exposes the StatView metrics through JMX :)

It is recommended to use the latest version of audacity to generate OGG/Vorbis files (its guaranteed to work!). The OGG loader will choke on older OGG files from many years ago ...

For posterity: I recoded an MP3 into the troublesome OGG using VLC 2.0.1, I’ll try Audacity next time.



Ironic thing is I tried with Audacity first but I couldn’t manage to compile in MP3-decoder support in the latest audacity on my Debian machine and then I gave up and went with VLC :slight_smile:

Have you tried converting MP3 to WAV using VLC? Generally that step can’t fail since WAV is a fairly standard format. Then you can give the WAV to Audacity or other tools for conversion.

@Momoko_Fan said:
Have you tried converting MP3 to WAV using VLC? Generally that step can't fail since WAV is a fairly standard format. Then you can give the WAV to Audacity or other tools for conversion.

Yeah that is a good way that probably won't fail. In this case I'm pretty happy with just using a wav although it is uncompressed. Thank you all for your time in helping me with this.