My use case: "low memory" usage of PMS for my Intel Atom N270/1Gb server (with other tasks to do in the 1Gb), to serve videos from the plugin UitzendingGemist to my media player (WD TV live).
Result: Everything works fine with less than 40M total memory used for Java.
But: My version needed a bit of hacking on the source code. I did not file anything as bug/issue, because on the issue list and forum the devs are generally not working to optimize PMS for low memory type usage. That is a fine choice, but I wanted to use PMS for this type of usage anyhow
Warning: only tested with UitzendingGemist.jar and a few output profiles. Uitzending Gemist contains broadcast shows with low resolution WMV video/audio. I did test with vlc,mencoder (transcoding) and mplayer (just dump), all work fine. I did not test stuff like sending local 1080p uncompressed video, but I am (almost) sure that will not work in this setup....
How?
Actually PMS is not very demanding of memory to start with. With mentioned plugin loaded, but without the videobuffer (more on that later), PMS typically uses around 4M on the heap without and 8M with the GUI. Besides the (dynamic) heap, PMS uses around 20M 'PermGen' memory. Java uses this type of memory to load the classes/jvm and static data. This is somewhat high, (presumably) because of the usage of a lot of 3rd party libs.
So if we can keep the buffer low, memory usage is low. Now you can actually configure PMS in the Gui on the Trancoding tab, or in PMS.conf to set a maximum buffer size. I set it to 4M an monitored the program with jvisualm and TRACE logging. No succes yet, after setting the max buffer the actually assigned buffer started with 50M (the hardcoded initial buffer size) and shortly after that raised to 100M.
This is because 100M is the hardcoded lower limit for the maximum buffer, so we need to remove this barrier. In OutputParams.java, remove these lines:
- Code: Select all
if (maxBufferSize < 100) {
maxBufferSize = 100;
}
This is not enough for Mplayer, which looks at a different configuration key for the max buffer, so in MplayerWebVideoDump.java remove these lines:
- Code: Select all
params.minBufferSize = params.minFileSize;
params.secondread_minsize = 100000;
params.waitbeforestart = 6000;
params.maxBufferSize = PMS.getConfiguration().getMaxAudioBuffer();
Add the following settings (on linux in ~/.config/PMS/PMS.conf) for a 4MB buffer:
- Code: Select all
minvideobuffer = 1
maxvideobuffer = 4
key_videotranscode_start_delay = 1
And you are done: a lower memory usage for PMS! I use two more tweaks. As said before, the permgen mem is 20MB, which can be lowered a bit (by 5Mb or so) if you are starting the server in headless/console mode anyway. To do this you need to remove from PMS.java:
- Code: Select all
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
and the places this libraries are used. These are:
- Code: Select all
try {
Toolkit.getDefaultToolkit();
if (GraphicsEnvironment.isHeadless()) {
if (System.getProperty(NOCONSOLE) == null) {
System.setProperty(CONSOLE, Boolean.toString(true));
}
} else {
headless = false;
}
} catch (Throwable t) {
System.err.println("Toolkit error: " + t.getMessage());
if (System.getProperty(NOCONSOLE) == null) {
System.setProperty(CONSOLE, Boolean.toString(true));
}
}
and
- Code: Select all
if (!headless && displayProfileChooser) {
ProfileChooser.display();
}
and replace
- Code: Select all
if (System.getProperty(CONSOLE) == null) {
frame = new LooksFrame(autoUpdater, configuration);
} else {
System.out.println("GUI environment not available"); //$NON-NLS-1$
System.out.println("Switching to console mode"); //$NON-NLS-1$
frame = new DummyFrame();
}
}
with
- Code: Select all
frame = new DummyFrame();
and recompile. Now you have a console only PMS build.
The last thing I did is I hardcode a memory limit for Java, because I dislike the kernel killing other (more critical) processes on my server. This is not needed per se: Java gives back unused memory to the OS anyway. And the downside of these limit is that the streams can crash and that you cannot serve more than one stream simultaneously (with this limit). Of course you can change these values to something a little bit more sane and/or just lower the default memory size (-Xms).
In PMS.sh (on linux) add/replace after line with exec "$JAVA" $JAVA_OPTS
- Code: Select all
-Xmx20M -Xss1024k -XX:MaxPermSize=20M
Now you have a PMS server which never uses more than 40Mb memory. Tips or better options are of course welcome...
