I’ve been trying to figure out how to play .mid files without using a ton of RAM for the past two days and I’ve finally found some code that worked well. After a few tests and some profiling I noticed that the used RAM just kept going up and up so I decided that System.gc(); might fix this problem, it did.
My question is… Is it ok for me to be using System.gc(); like this? I’ve read that most people don’t know how to properly use it and that there shouldn’t be any need to use it so I’m not too sure if I should be using it. Using System.gc(); did take the used RAM from 60-130+mb before being reduced to a constant 35-40mb before being reduced.
Method that uses System.gc();
public void meta(MetaMessage event) {
if (event.getType() == END_OF_TRACK_MESSAGE)
{
if(sequencer != null && sequencer.isOpen() && loop)
{
sequencer.setMicrosecondPosition(0);
sequencer.start();
System.gc();
System.out.println("Test1");
}
else
{
sequencer.stop();
sequencer.close();
System.out.println("Test");
}
}
}
Whole class.
package Core;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
public class MidiPlayer implements MetaEventListener {
// Midi meta event
public static final int END_OF_TRACK_MESSAGE = 47;
private Sequencer sequencer;
private boolean loop;
private boolean paused;
/**
* Creates a new MidiPlayer object.
*/
public MidiPlayer() {
try {
sequencer = MidiSystem.getSequencer();
sequencer.open();
sequencer.addMetaEventListener(this);
} catch (MidiUnavailableException ex) {
sequencer = null;
}
}
/**
* Loads a sequence from the file system. Returns null if an error occurs.
*/
public Sequence getSequence(String filename) {
try {
return getSequence(new FileInputStream(filename));
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
}
/**
* Loads a sequence from an input stream. Returns null if an error occurs.
*/
public Sequence getSequence(InputStream is) {
try {
if (!is.markSupported()) {
is = new BufferedInputStream(is);
}
Sequence s = MidiSystem.getSequence(is);
is.close();
return s;
} catch (InvalidMidiDataException | IOException ex) {
ex.printStackTrace();
return null;
}
}
/**
* Plays a sequence, optionally looping. This method returns immediately.
* The sequence is not played if it is invalid.
*/
public void play(Sequence sequence, boolean loop) {
if (sequencer != null && sequence != null && sequencer.isOpen()) {
try {
sequencer.setSequence(sequence);
sequencer.start();
this.loop = loop;
} catch (InvalidMidiDataException ex) {
ex.printStackTrace();
}
}
}
/**
* This method is called by the sound system when a meta event occurs. In
* this case, when the end-of-track meta event is received, the sequence is
* restarted if looping is on.
*/
@Override
public void meta(MetaMessage event) {
if (event.getType() == END_OF_TRACK_MESSAGE)
{
if(sequencer != null && sequencer.isOpen() && loop)
{
sequencer.setMicrosecondPosition(0);
sequencer.start();
System.gc();
System.out.println("Test1");
}
else
{
sequencer.stop();
sequencer.close();
System.out.println("Test");
}
}
}
/**
* Stops the sequencer and resets its position to 0.
*/
public void stop() {
if (sequencer != null && sequencer.isOpen()) {
sequencer.stop();
sequencer.setMicrosecondPosition(0);
}
}
/**
* Closes the sequencer.
*/
public void close() {
if(sequencer != null && sequencer.isOpen()) {
sequencer.close();
}
}
/**
* Gets the sequencer.
*/
public Sequencer getSequencer() {
return sequencer;
}
/**
* Sets the paused state. Music may not immediately pause.
*/
public void setPaused(boolean paused) {
if(this.paused != paused && sequencer != null && sequencer.isOpen()) {
this.paused = paused;
if (paused) {
sequencer.stop();
} else {
sequencer.start();
}
}
}
/**
* Returns the paused state.
*/
public boolean isPaused() {
return paused;
}
}