Memory Consumption is always increasing in Humble-Video - java

I have been using humble-video in a live streaming project to convert flv to mp4. I've realized that java process's(in which humble-video codes are running) memory usage is always increasing when looking with top command.
After that I changed the demo source code of the humble-video and put the segmentFile function in an infinite loop and memory usage of the process is again always increasing when looking with top command. It is over 2.5GiB and has been running for about 30 mins.
I expect the process's memory consumption to stay stable somewhere between 40-50MB not to keep increasing always.
Do you have any idea about that?

I've resolved the problem.
The problem is Garbage Collector does not clear WeakReferences so that JNIMemoryManager does not delete native objects. Calling System.gc() after every iteration is helping but it is not the exact solution.
The solution is that calling delete() at the end of each iteration. Some objects are created which you may not expect during the execution so please look at which objects are created with JNIMemoryManager.getMgr().dumpMemoryLog(); and look at how many objects are alive with JNIMemoryManager.getMgr().getNumPinnedObjects();
The last state of the segmentFile function is as below and memory consumption still stays about 80 MiB at the end of 15min.
private void segmentFile(String input, String output, int hls_start,
int hls_time, int hls_list_size, int hls_wrap, String hls_base_url,
String vFilter,
String aFilter) throws InterruptedException, IOException {
JNIMemoryManager.getMgr().setMemoryDebugging(true);
Demuxer demuxer = Demuxer.make();
demuxer.open(input, null, false, true, null, null);
// we're forcing this to be HTTP Live Streaming for this demo.
Muxer muxer = Muxer.make(output, null, "hls");
muxer.setProperty("start_number", hls_start);
muxer.setProperty("hls_time", hls_time);
muxer.setProperty("hls_list_size", hls_list_size);
muxer.setProperty("hls_wrap", hls_wrap);
if (hls_base_url != null && hls_base_url.length() > 0)
muxer.setProperty("hls_base_url", hls_base_url);
MuxerFormat format = MuxerFormat.guessFormat("mp4", null, null);
/**
* Create bit stream filters if we are asked to.
*/
BitStreamFilter vf = vFilter != null ? BitStreamFilter.make(vFilter) : null;
BitStreamFilter af = aFilter != null ? BitStreamFilter.make(aFilter) : null;
int n = demuxer.getNumStreams();
DemuxerStream[] demuxerStreams = new DemuxerStream[n];
Decoder[] decoders = new Decoder[n];
List<MuxerStream> muxerStreamList = new ArrayList();
for(int i = 0; i < n; i++) {
demuxerStreams[i] = demuxer.getStream(i);
decoders[i] = demuxerStreams[i].getDecoder();
Decoder d = decoders[i];
if (d != null) {
// neat; we can decode. Now let's see if this decoder can fit into the mp4 format.
if (!format.getSupportedCodecs().contains(d.getCodecID())) {
throw new RuntimeException("Input filename (" + input + ") contains at least one stream with a codec not supported in the output format: " + d.toString());
}
if (format.getFlag(MuxerFormat.Flag.GLOBAL_HEADER))
d.setFlag(Coder.Flag.FLAG_GLOBAL_HEADER, true);
d.open(null, null);
muxerStreamList.add(muxer.addNewStream(d));
}
}
muxer.open(null, null);
n = muxer.getNumStreams();
MuxerStream[] muxerStreams = new MuxerStream[n];
Coder[] coder = new Coder[n];
for (int i = 0; i < n; i++) {
muxerStreams[i] = muxer.getStream(i);
if (muxerStreams[i] != null) {
coder[i] = muxerStreams[i].getCoder();
}
}
MediaPacket packet = MediaPacket.make();
while(demuxer.read(packet) >= 0) {
/**
* Now we have a packet, but we can only write packets that had decoders we knew what to do with.
*/
final Decoder d = decoders[packet.getStreamIndex()];
if (packet.isComplete() && d != null) {
// check to see if we are using bit stream filters, and if so, filter the audio
// or video.
if (vf != null && d.getCodecType() == Type.MEDIA_VIDEO)
vf.filter(packet, null);
else if (af != null && d.getCodecType() == Type.MEDIA_AUDIO)
af.filter(packet, null);
muxer.write(packet, false);
}
}
// It is good practice to close demuxers when you're done to free
// up file handles. Humble will EVENTUALLY detect if nothing else
// references this demuxer and close it then, but get in the habit
// of cleaning up after yourself, and your future girlfriend/boyfriend
// will appreciate it.
muxer.close();
demuxer.close();
muxer.delete();
demuxer.delete();
packet.delete();
format.delete();
vf.delete();
muxer = null;
demuxer = null;
packet = null;
format = null;
vf = null;
for (int i=0; i < muxerStreams.length; i++) {
if (muxerStreams[i] != null) {
muxerStreams[i].delete();
muxerStreams[i] = null;
}
if (coder[i] != null) {
coder[i].delete();
coder[i] = null;
}
}
for (int i=0; i < demuxerStreams.length; i++) {
if (demuxerStreams[i] != null) {
demuxerStreams[i].delete();
demuxerStreams[i] = null;
}
if (decoders[i] != null) {
decoders[i].delete();
decoders[i] = null;
}
}
for (Iterator iterator = muxerStreamList.iterator(); iterator.hasNext();) {
MuxerStream muxerStream = (MuxerStream) iterator.next();
if (muxerStream != null) {
muxerStream.delete();
muxerStream = null;
}
}
muxerStreamList.clear();
muxerStreamList = null;
System.out.println("number of alive objects:" + JNIMemoryManager.getMgr().getNumPinnedObjects());
}

Related

Not able to get the specific location of the bookmark in a page using PDFBOX

I am using PDFBOX 2.0.2 jar to add more than one PDF in a existing heading bookmarked PDF file. And for the same i am splitting it and merging other PDF.
Splitter splitter = new Splitter();
splitter.setStartPage(1);
splitter.setEndPage(noOfPagesInHeadingBkmrkedPDF);
Before Split and merge , i am keeping all the bookmark in HashMap with key as pageNumber and value as bookmark name. And after merge i am setting back the bookmark w.r.t. My query is - how to get the specific co-ordinate (location) of bookmark on the page so that the after merge i should be able to set it back to that particular location of the page.
Code snippet for creating the HashMap before Split :
public void getAllBookmarks(PDOutlineNode bookmarksInOriginalFile, String emptyString, Map<Integer, String> bookmarkMap) throws IOException {
PDOutlineItem current = null;
if (null != bookmarksInOriginalFile)
current = bookmarksInOriginalFile.getFirstChild();
while (current != null) {
Integer pageNumber = 0;
PDPageDestination pd = null;
if (current.getDestination() instanceof PDPageDestination) {
pd = (PDPageDestination) current.getDestination();
pageNumber = (pd.retrievePageNumber() + 1); // Do we have any method available to get the location on the specific page ??
}
if (current.getAction() instanceof PDActionGoTo) {
PDActionGoTo gta = (PDActionGoTo) current.getAction();
if (gta.getDestination() instanceof PDPageDestination) {
pd = (PDPageDestination) gta.getDestination();
pageNumber = (pd.retrievePageNumber() + 1);
}
}
String bookmarkName = emptyString + current.getTitle();
if(null!=bookmarkName && !EMPTY_STRING.equalsIgnoreCase(bookmarkName)){
bookmarkMap.put(pageNumber-1,bookmarkName);
}
getAllBookmarks(current, emptyString,bookmarkMap);
current = current.getNextSibling();
}
}
Any help would be much appreciated.
Thank you...
As i am able to solve my solution using #TilmanHausherr Suggestion. I am answering my question. I changed the below piece of code :
public void getAllBookmarks(PDOutlineNode bookmarksInOriginalFile, String emptyString, Map<Integer,BookmarkMetaDataBO> bookmarkMap) throws IOException {
PDOutlineItem current = null;
if (null != bookmarksInOriginalFile)
current = bookmarksInOriginalFile.getFirstChild();
while (current != null) {
Integer pageNumber = 0;
PDPageDestination pd = null;
PDPageXYZDestination pdx = null;
// These value will give the specific location
**int left = 0;
int top = 0;**
if (current.getDestination() instanceof PDPageXYZDestination) {
pdx = (PDPageXYZDestination) current.getDestination();
pageNumber = (pdx.retrievePageNumber() + 1);
**left = pdx.getLeft();
top = pdx.getTop();**
}
if (current.getAction() instanceof PDActionGoTo) {
PDActionGoTo gta = (PDActionGoTo) current.getAction();
if (gta.getDestination() instanceof PDPageDestination) {
pd = (PDPageDestination) gta.getDestination();
pageNumber = (pd.retrievePageNumber() + 1);
}
}
String bookmarkName = emptyString + current.getTitle();
if(null!=bookmarkName && !EMPTY_STRING.equalsIgnoreCase(bookmarkName)){
BookmarkMetaDataBO bkmrkBo = new BookmarkMetaDataBO();
**bkmrkBo.setTop(left);
bkmrkBo.setLeft(top);**
bookmarkMap.put(pageNumber-1,bkmrkBo);
}
getAllBookmarks(current, emptyString,bookmarkMap);
current = current.getNextSibling();
}
}
Thank you...

How to modify the iterator when hashset values are added

I have written code for to find out the broken links present in the website using selenium webdriver in java. As links are getting added in the HashSet while launching the different urls. I have tried to read the added urls from HashSet it stops executing after sometime. This is happening because iterator remains as it is even adding of new links to the HashSet. I want that execution should continue for all links present in the HashSet.
[I have tried to convert Set to an array but duplicate links are executing multiple times.]
public Set<String> unique_links;
HashMap<String, String> result;
Set<String> finalLinkSet = new HashSet<>();
Set<String> hs = new HashSet<>();
Set<String> uniqueLinkSet = new HashSet<>();
// String[] finalLinkArray;
String[] finalLinkArray;
boolean isValid = false;
FileWriter fstream;
BufferedWriter out;
int count = 1;
int FC = 0;
Set<String> secondaryset = new HashSet<>();
// String Responsecode = null;
#Test
public void LinkTesting() throws IOException, RowsExceededException,
WriteException {
w.manage().deleteAllCookies();
unique_links = new HashSet<String>();
w.get("http://www.skyscape.com");
ArrayList<WebElement> urlList = new ArrayList<WebElement>();
urlList = (ArrayList<WebElement>) w.findElements(By.tagName("a"));
setFinalLinkSet(getUniqueList(urlList));
for(Iterator<String> i = finalLinkSet.iterator(); i.hasNext(); ) {
System.out.println(finalLinkSet.size());
String currenturl = (String) i.next();
if ((currenturl.length() > 0 && currenturl
.startsWith("http://www.skyscape.com"))) {
if (!currenturl.startsWith("http://www.skyscape.com/estore/")&&
(!currenturl.startsWith("http://www.skyscape.com/demos/"))) {
System.out.println(currenturl);
getResponseCode(currenturl);
}
}
}
writetoexcel();
}
public void setFinalLinkSet(Set<String> finalLinkSet) {
this.finalLinkSet = finalLinkSet;
}
// function to get link from page and return array list of links
public Set<String> getLinksOnPage(String url) {
ArrayList<WebElement> secondaryUrl = new ArrayList<WebElement>();
secondaryUrl = (ArrayList<WebElement>) w.findElements(By.tagName("a"));
for (int i = 0; i < secondaryUrl.size(); i++) {
secondaryset.add((secondaryUrl.get(i).getAttribute("href")
.toString()));
}
return secondaryset;
}
// function to fetch link from array list and store unique links in hashset
public Set<String> getUniqueList(ArrayList<WebElement> url_list) {
for (int i = 0; i < url_list.size(); i++) {
uniqueLinkSet.add(url_list.get(i).getAttribute("href").toString());
}
return uniqueLinkSet;
}
public boolean getResponseCode(String url) {
boolean isValid = false;
if (result == null) {
result = new HashMap<String, String>();
}
try {
URL u = new URL(url);
w.navigate().to(url);
HttpURLConnection h = (HttpURLConnection) u.openConnection();
h.setRequestMethod("GET");
h.connect();
System.out.println(h.getResponseCode());
if ((h.getResponseCode() != 500) && (h.getResponseCode() != 404)
&& (h.getResponseCode() != 403)
&& (h.getResponseCode() != 402)
&& (h.getResponseCode() != 400)
&& (h.getResponseCode() != 401)) {
// && (h.getResponseCode() != 302)) {
//getLinksOnPage(url);
Set<String> unique2 = getLinksOnPage(url);
setFinalLinkSet(unique2);
result.put(url.toString(), "" + h.getResponseCode());
} else {
result.put(url.toString(), "" + h.getResponseCode());
FC++;
}
return isValid;
} catch (Exception e) {
}
return isValid;
}
private void writetoexcel() throws IOException, RowsExceededException,
WriteException {
FileOutputStream fo = new FileOutputStream("OldLinks.xls");
WritableWorkbook wwb = Workbook.createWorkbook(fo);
WritableSheet ws = wwb.createSheet("Links", 0);
int recordsToPrint = result.size();
Label HeaderUrl = new Label(0, 0, "Urls");
ws.addCell(HeaderUrl);
Label HeaderCode = new Label(1, 0, "Response Code");
ws.addCell(HeaderCode);
Label HeaderStatus = new Label(2, 0, "Status");
ws.addCell(HeaderStatus);
Iterator<Entry<String, String>> it = result.entrySet().iterator();
while (it.hasNext() && count < recordsToPrint) {
String Responsecode = null;
Map.Entry<String, String> pairs = it.next();
System.out.println("Value is --" + pairs.getKey() + " - "
+ pairs.getValue() + "\n");
Label Urllink = new Label(0, count, pairs.getKey());
Label RespCode = new Label(1, count, pairs.getValue());
Responsecode = pairs.getValue();
System.out.println(Responsecode);
if ((Responsecode.equals("500")) || (Responsecode.equals("404"))
|| (Responsecode.equals("403"))
|| (Responsecode.equals("400"))
|| (Responsecode.equals("402"))
|| (Responsecode.equals("401"))) {
// || (Responsecode.equals("302"))) {
Label Status1 = new Label(2, count, "Fail");
ws.addCell(Status1);
} else {
Label Status2 = new Label(2, count, "Pass");
ws.addCell(Status2);
}
try {
ws.addCell(Urllink);
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
ws.addCell(RespCode);
count++;
}
Label FCS = new Label(4, 1, "Fail Urls Count is = " + FC);
ws.addCell(FCS);
wwb.write();
wwb.close();
}
}
In short, as far as I understand the problem: You have (at least) two threads (although I couldn't find them in the too long code example), one is adding entries to the HashSet, and the other should continuously list elements as they are added to the HashSet.
1st: You should use a concurrent data structure for this, but not a simple HashSet.
2nd: Iterators of HashSet do not support concurrent modification, so you can now have an iterator "waiting" for new entries being added.
Best is to change your code to use some kind of event-message pattern (sometimes also called broadcaster/listener), where the finding of a new URL generates an event, that other parts of your code listen to and then write them to the file.
Your loop finishes (earlier than desired) for the following reasons:
The initiation part Iterator<String> i = finalLinkSet.iterator()of your for-loop
for(Iterator<String> i = finalLinkSet.iterator(); i.hasNext(); ) {
is evaluated once when the loop is started. Hence it will not react on changes to finalLinkSet even if there where some.
You are not making any changes to finalLinkSet. Instead you are overwriting it with a new set when calling
setFinalLinkSet(unique2);
So instead you should:
Use a list, so you have ordered elements. (Adding entries to an unordered set will make it impossible to know which ones you already have iterated over). I suggest you therefore use an ArrayList<String>, so you have constant access time by the little drawback of performance for resizing on adding new entries.
Modify your for-loop to use an index, so evaluating the init-part once is sufficient and you can react on the changing size of list:
for(int i = 0; i < finalLinkList.size(); i++) {
System.out.println(finalLinkSet.size());
String currenturl = (String) finalLinkList.get(i);
Then instead of overwriting the list you should:
// for both occurrences
addToFinalLinkList(...); // see new code below
and
public void addToFinalLinkList(Set<String> tempSet) {
for(String url: tempSet)
{
if(!finalLinkList.contains(url))
finalListList.add(url);
}
}
I know this is not best from the performance point of view, but since you are inside a test, this shouldn't be a problem from what I see...

How to re-code a movie file with Xuggler

This must be a very stupid question, but how does one recode with Xuggler?
Simplified I have:
IMediaReader reader = ToolFactory.makeReader(sourceUrl);
IMediaWriter writer = ToolFactory.makeWriter(url, reader);
MediaSegmenterWriter writerListener = new MediaSegmenterWriter();
writer.open();
while (reader.readPacket() == null)
do {
}
while(false);
Now, I want to recode the file in the reader to another bitrate and resolution. How do I do that? On creating the writer I have tried to add IMediaStreams with a copy of the original coder with the necessary changes, but that does not work:
int numStreams = reader.getContainer().getNumStreams();
for(int i = 0; i < numStreams; i++)
{
final IStream stream = reader.getContainer().getStream(i);
final IStreamCoder coder = stream.getStreamCoder();
IStreamCoder newCoder = IStreamCoder.make(IStreamCoder.Direction.ENCODING, coder);
if(newCoder == null ){
continue;
}
writer.getContainer().addNewStream(i);
int streams = writer.getContainer().getNumStreams();
System.out.println("Current amount of streams in writer: " + streams);
System.out.println("Coder: " + coder.toString());
if (coderSetting != null && newCoder != null){
if (newCoder.getCodecType().equals(ICodec.Type.CODEC_TYPE_VIDEO)) {
newCoder.setWidth(320);
newCoder.setHeight(240);
}
IStream outputStream = writer.getContainer().getStream(i);
outputStream.setStreamCoder(newCoder);
newCoder.open();
}
}
But this just gives the same result as leaving the code out (e.g. 1920x1080 from original)
Also tried to add a listener to the writer and replace the coder, but either got an error (coder already opened_ or no effect. (on onOpen, onAddStream, onOpenCoder))
I looked for tutorials, but non seem to do this simple operation.
Any help would be REALLY appreciated!!!
In order to resize the content as well as recode you need to create a MediaToolAdapter like:
private static class MediaResizer extends MediaToolAdapter {
private IVideoResampler videoResampler = null;
private int mediaHeight;
private int mediaWidth;
public MediaResizer (int aHight, int aWidth) {
mediaWidth = aWidth;
mediaHeight = aHeight;
}
#Override
public void onVideoPicture(IVideoPictureEvent event) {
// In case of audio only, do not re-size as it is not needed
if(job.role == MediaRole.MediaRoleEnum.LS_AUDIO) super.onVideoPicture(event);
IVideoPicture pic = event.getPicture();
if (videoResampler == null) {
videoResampler = IVideoResampler.make(job.getCoderSettings().width, job.getCoderSettings().height, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
}
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), mediaWidth, mediaHeight);
videoResampler.resample(out, pic);
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
super.onVideoPicture(asc);
out.delete();
}
}
You add this as a listener to your reader, and then your writer to you resized. It should be something like:
IMediaReader reader = ToolFactory.makeReader(sourceUrl);
MediaResizer resizer = new MediaResizer(job);
IMediaWriter currentWriter = ToolFactory.makeWriter(destinationDir, reader);
reader.addListener(resizer);
resizer.addListener(currentWriter);
#Muhammad Umar,
Maybe he means:
#Override
public void onVideoPicture(IVideoPictureEvent event) {
// Logger.info("onAddStream(): now I am in VideoConverter.onVideoPicture().....");
IVideoPicture pic = event.getPicture();
if (videoResampler == null) {
videoResampler = IVideoResampler.make(VIDEO_WIDTH, VIDEO_HEIGHT,
pic.getPixelType(), pic.getWidth(), pic.getHeight(),
pic.getPixelType());
}
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), VIDEO_WIDTH, VIDEO_HEIGHT);
videoResampler.resample(out, pic);
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
super.onVideoPicture(asc);
out.delete();
}

How to convert serialClob to String format?

I am trying to convert serialclob to string. But I am not successful. I think I am not doing in the correct way. My code is:
char[] buffer;
int count = 0;
int length = 0;
String data = null;
String[] type;
StringBuffer sb;
try{
SqlRowSet rows = getJdbcTemplate().queryForRowSet("select c.BOUNDING_BOX.GET_WKT() BOUNDING_BOX FROM EXAMPLE c WHERE EXAMPLE_ID = 100",
new Object[] {subid});
SubscriptionModel subscription = new SubscriptionModel();
System.out.println("bbox");
SqlRowSetMetaData rsmd = rows.getMetaData();
type = new String[rsmd.getColumnCount()];
for(int col=0;col<rsmd.getColumnCount();col++)
type[col] = rsmd.getColumnTypeName(col + 1);
System.out.println("Read rows and only serial clob data type values");
while(rows.next()){
System.out.println("test 1 here");
for(int col=0;col<rsmd.getColumnCount();col++){
System.out.println("test 2 here");
if("CLOB".equals(type[col]){
System.out.println("test 3 here");
SerialClob clob = (SerialClob) ((ResultSet) rows).getClob(col + 1);
if(clob != null){
System.out.println("clob is not null");
Reader is = clob.getCharacterStream();
sb = new StringBuffer();
length = (int) clob.length();
if(length>0){
buffer = new char[length];
count = 0;
try{
while((count = is.read(buffer)) != -1)
sb.append(buffer);
data = new String(sb);
}catch(Exception e){
}
}
else
data = (String) null;
}else
data = (String) null;
}else{
data = (String) rows.getObject(col + 1);
}
}
}
return subscription;
}catch(Exception e){
e.printStackTrace();
}
But I am getting an error like:
bbox
Read rows and only serial clob data type values
test 1 here
test 2 here
java.lang.ClassCastException: javax.sql.rowset.serial.SerialClob cannot be cast to java.lang.String
Where is my mistake?
Well this is at least one problem:
if(type[col] == "CLOB")
That's comparing string references directly. I suspect this would work better:
if ("CLOB".equals(type[col]))
That will get you into the right if block. I haven't looked in detail at the rest of your code - it would be simpler to read and maintain if you could break it up into smaller methods.
The problem is most likely here --
if(type[col] == "CLOB"){ // <-- This does Object equality
Use String#equals() method to do String comparisons.
if ( "CLOB".equals(type[col]) ) {

Get memory and CPU usage

I would like to get the total physical memory, the CPU usage, and and the amount of memory being used. I have looked into Runtime.freeMemory(), but that isn't the free memory for the whole system.
I know I'm late with my answer, but I think this code is interesting.
This is an adaptation of "closed" code, and should be revised before aplying directly:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.Process;
import java.lang.Runtime;
import java.util.HashMap;
/**
* SystemStatusReader is a collection of methods to read system status (cpu and memory)
*
* #author Andreu Correa Casablanca
*/
public class SystemStatusReader
{
public static final int CONSERVATIVE = 0;
public static final int AVERAGE = 1;
public static final int OPTIMISTIC = 2;
/**
* cpuUsage gives us the percentage of cpu usage
*
* mpstat -P ALL out stream example:
*
* Linux 3.2.0-30-generic (castarco-laptop) 10/09/12 _x86_64_ (2 CPU) - To discard
* - To discard
* 00:16:30 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle - To discard
* 00:16:30 all 17,62 0,03 3,55 0,84 0,00 0,03 0,00 0,00 77,93
* 00:16:30 0 17,36 0,05 3,61 0,83 0,00 0,05 0,00 0,00 78,12
* 00:16:30 1 17,88 0,02 3,49 0,86 0,00 0,01 0,00 0,00 77,74
*
* #param measureMode Indicates if we want optimistic, convervative or average measurements.
*/
public static Double cpuUsage (int measureMode) throws Exception {
BufferedReader mpstatReader = null;
String mpstatLine;
String[] mpstatChunkedLine;
Double selected_idle;
try {
Runtime runtime = Runtime.getRuntime();
Process mpstatProcess = runtime.exec("mpstat -P ALL");
mpstatReader = new BufferedReader(new InputStreamReader(mpstatProcess.getInputStream()));
// We discard the three first lines
mpstatReader.readLine();
mpstatReader.readLine();
mpstatReader.readLine();
mpstatLine = mpstatReader.readLine();
if (mpstatLine == null) {
throw new Exception("mpstat didn't work well");
} else if (measureMode == SystemStatusReader.AVERAGE) {
mpstatChunkedLine = mpstatLine.replaceAll(",", ".").split("\\s+");
selected_idle = Double.parseDouble(mpstatChunkedLine[10]);
} else {
selected_idle = (measureMode == SystemStatusReader.CONSERVATIVE)?200.:0.;
Double candidate_idle;
int i = 0;
while((mpstatLine = mpstatReader.readLine()) != null) {
mpstatChunkedLine = mpstatLine.replaceAll(",", ".").split("\\s+");
candidate_idle = Double.parseDouble(mpstatChunkedLine[10]);
if (measureMode == SystemStatusReader.CONSERVATIVE) {
selected_idle = (selected_idle < candidate_idle)?selected_idle:candidate_idle;
} else if (measureMode == SystemStatusReader.OPTIMISTIC) {
selected_idle = (selected_idle > candidate_idle)?selected_idle:candidate_idle;
}
++i;
}
if (i == 0) {
throw new Exception("mpstat didn't work well");
}
}
} catch (Exception e) {
throw e; // It's not desirable to handle the exception here
} finally {
if (mpstatReader != null) try {
mpstatReader.close();
} catch (IOException e) {
// Do nothing
}
}
return 100-selected_idle;
}
/**
* memoryUsage gives us data about memory usage (RAM and SWAP)
*/
public static HashMap<String, Integer> memoryUsage () throws Exception {
BufferedReader freeReader = null;
String freeLine;
String[] freeChunkedLine;
HashMap<String, Integer> usageData = new HashMap<String, Integer>();
try {
Runtime runtime = Runtime.getRuntime();
Process freeProcess = runtime.exec("free -k"); // We measure memory in kilobytes to obtain a greater granularity
freeReader = new BufferedReader(new InputStreamReader(freeProcess.getInputStream()));
// We discard the first line
freeReader.readLine();
freeLine = freeReader.readLine();
if (freeLine == null) {
throw new Exception("free didn't work well");
}
freeChunkedLine = freeLine.split("\\s+");
usageData.put("total", Integer.parseInt(freeChunkedLine[1]));
freeLine = freeReader.readLine();
if (freeLine == null) {
throw new Exception("free didn't work well");
}
freeChunkedLine = freeLine.split("\\s+");
usageData.put("used", Integer.parseInt(freeChunkedLine[2]));
freeLine = freeReader.readLine();
if (freeLine == null) {
throw new Exception("free didn't work well");
}
freeChunkedLine = freeLine.split("\\s+");
usageData.put("swap_total", Integer.parseInt(freeChunkedLine[1]));
usageData.put("swap_used", Integer.parseInt(freeChunkedLine[2]));
} catch (Exception e) {
throw e;
} finally {
if (freeReader != null) try {
freeReader.close();
} catch (IOException e) {
// Do nothing
}
}
return usageData;
}
}
You can use SIGAR (http://support.hyperic.com/display/SIGAR/Home). I believe this is cross platform (I've only tried it on Windows) and I know it works (because I've tried it).
Javadoc: http://www.hyperic.com/support/docs/sigar/
Binaries: http://support.hyperic.com/display/SIGAR/Home#Home-binaries
Memory and CPU.
CPU example:
static final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
...
long start = threadBean.getCurrentThreadCpuTime();
for (int i = 0; i < 10000000; i++) {
...
}
long finish = threadBean.getCurrentThreadCpuTime();
On Linux you could open /proc/meminfo as a text file and parse the result.
Use JMX via 'jconsole', if this if for interactive use. It displays nice realtime graphs, and lots of other diagnostic information.

Categories