Why using getFreeSpace /getTotalSpace / getUsableSpace gives different output from df -H command - java

I have an external SSD disk (/dev/sda).
when typing df -h:
size used avil use%
587G 383G 175G 69%
when typing df -H:
size used avil use%
630G 411G 188G 69%
When using getTotalSpace() / (1024*1024) I'm getting: 600772
When using getUsableSpace() / (1024*1024) I'm getting: 178568
When using getFreeSpace() / (1024*1024) I'm getting: 209108
If I will try to calculate the usage in parentage I will not get 69%.
What is the bug ?

The 69% of df is calculated as "used / (used + available)" which is 383 / (383 + 175) = 69%. It's not calculated as "used / size".
You don't have "used" in Java (it's not the same as "size - available") so you can't make the same calculation.
But you can calculate "available / size" in both cases:
188 / 630 = 30%
209108 / 600772 = 30%
There is no bug. You were comparing different things.

Related

JDK11 getFreeSpace and getTotalSpace from File is not matching df

I am seeing df -h giving output like below
root#vrni-platform:/var/lib# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg-var 110G 94G 11G 91% /var
root#vrni-platform:/var/lib# df -k
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/vg-var 114756168 98318504 10585300 91% /var
But if I do the same from java like below
final File dataPath = new File("/var");
final long totalBytes = dataPath.getTotalSpace();
final long usedBytes = totalBytes - dataPath.getFreeSpace();
System.out.printf("Disk utilization: %.2f, Total bytes: %d, Used Bytes: %d", ((double)usedBytes/totalBytes * 100), totalBytes, usedBytes);```
It is printing like below
Disk utilization: 85.68, Total bytes: 117510316032, Used Bytes: 100678909952
Can someone let me know why is this discrepancy in disk utilization?
Environment
Ubuntu 18.04
Java - Zulu OpenJDK 11.0.11
As I also mentioned in the comments, the primary reason is that getFreeSpace seems to report something else than DFs 'Avail' or 'Available'. Going by DFs '1K-blocks' and 'Used', you also get a percentage of 85,68%, while going by '1K-blocks' and 'Available' yields 91%. Also observe how DFs 'Used' and 'Available' (and 'Used' and 'Avail') do not add up to '1K-blocks' (or 'Size')
As suggested by user16320675, using getUsableSpace might be a better method to use than getFreeSpace. As to the reasons for the difference between '1K-blocks' - 'Used' and 'Available' in df, it might be better to ask that on https://unix.stackexchange.com/.

How can I get the CPU usage of a process with "tasklist" in Windows

I am writing a program in Java to periodically display the CPU and memory usage of a given process ID. My implementation invokes tasklist. It is pretty straightforward to get the memory usage by the following command:
tasklist /fi "memusage ge 0" /fi "pid eq 2076" /v
This will return the memory usage of process id 2076 and i can use this for my task. By invoking the following command, I can extract the CPU Time.
tasklist /fi "pid eq 2076" /fi "CPUTIME ge 00:00:00" /v
My question is, how would I go about getting the CPU usage of this process?
I found a post on StackOverflow for my question but the answer isn't clear and I don't understand what to type in the command to get what I need. The question was answered in 2008 and someone asked for clarification in 2013 but the person that answered the question hasn't replied.
Here is the post that I have found.
Memory is like a tea cup, it maybe full or empty, an instantaneous look at the cup allows you to see how full of tea it is (that is your "memusage" command).
CPU is like a ski lift. It moves at a reasonably constant rate irrespective of whether your are riding the lift or not. It is not possible to determine your usage in a single instantaneous observation - we need to know how long you were riding it for (that is your "cputime" command). You have to use the "cputime" command at least twice!
For example:
At 7:09 pm, you run the cputime command on your process, and it returns "28 minutes"
At 7:17 pm, you run the cputime command on your process again, and it returns "32 minutes"
From the first time you ran the cputime command to the second time, the usage has increased from 28 minutes to 32 minutes -- the process has used 4 minutes of CPU time.
From 7:09pm to 7:17pm is a duration of 8 minutes -- A total of 8 minutes of time were available, but your process just used 4 minutes: 4 / 8 = 50% average system usage.
If your system has multiple processors, then you can divide by the total number of CPUs to get an average per CPU - e.g. 50% / 2 = 25% average in a dual cpu system.
I used minutes above for ease of writing - in reality you may be looking at how many nanoseconds of CPU time the process used during a time window that is just milliseconds long.
tasklist does not provide the information you are looking for. I would suggest using Get-Counter. A comment on an answer from the SuperUser site looks to be on track for what you're after.
Get-Counter '\Process(*)\% Processor Time' | Select-Object -ExpandProperty countersamples| Select-Object -Property instancename, cookedvalue| ? {$_.instanceName -notmatch "^(idle|_total|system)$"} | Sort-Object -Property cookedvalue -Descending| Select-Object -First 25| ft InstanceName,#{L='CPU';E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}} -AutoSize
I once wrote a class:
private static class PerformanceMonitor {
private int availableProcessors = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
private long lastSystemTime = 0;
private long lastProcessCpuTime = 0;
/**
* Get's the cpu usage of the jvm
*
* #return the cpu usage a double of percentage
*/
private synchronized double getCpuUsage() {
if (lastSystemTime == 0) {
baselineCounters();
return 0d;
}
long systemTime = System.nanoTime();
long processCpuTime = 0;
if (getOperatingSystemMXBean() instanceof com.sun.management.OperatingSystemMXBean) {
processCpuTime = ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getProcessCpuTime();
}
double cpuUsage = ((double) (processCpuTime - lastProcessCpuTime)) / ((double) (systemTime - lastSystemTime));
lastSystemTime = systemTime;
lastProcessCpuTime = processCpuTime;
return cpuUsage / availableProcessors;
}
private void baselineCounters() {
lastSystemTime = System.nanoTime();
if (getOperatingSystemMXBean() instanceof com.sun.management.OperatingSystemMXBean) {
lastProcessCpuTime = ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getProcessCpuTime();
}
}
}
Which is used like:
private static final PerformanceMonitor _MONITOR = new PerformanceMonitor();
_MONITOR.getCpuUsage();
This prints out the usage of the cpu consumed by the process of this JVM.

Java Math Formula for calculating body fat percentages

Not sure why but I'm struggling to write this formula...
Double bf = 163.205 * log10(waist + hip - neck) - 97.684 * log10(height) - 78.387
It's the correct formula used to calculate body fat percentages. If I used various websites I have been able to get a sensible answer but in Java I seem to getting a minus answer.
Website
e.g waist = 29, hip = 38, neck = 12, height = 187
The order of mathmatics is incorrect when programming. How should this be wrote?
Here is a working version:
http://fitness.bizcalcs.com/Calculator.asp?Calc=Body-Fat-Navy
The formula you're using uses inches, while you're using centimeters.
This formula is for US Metrics, you use SI metrics values
For SI metrics you need:
for men: 86.010*log10(waist-neck) - 70.041*log10(height) + 30.30
for female: 163.205*log10(waist + hip - neck) - 97.684*log10(height) - 104.912

Java "No space left on device" but there is enough space on disk?

I'm trying to write files to the file system in a java programme but it fails with an exception throwing 'No space left on device' when df -h (and df -i) says otherwise.
Here is the output of df -h:
Filesystem Size Used Avail Use% Mounted on
udev 5.9G 4.0K 5.9G 1% /dev
tmpfs 1.2G 1.4M 1.2G 1% /run
/dev/sda5 156G 139G 9.1G 94% /
none 4.0K 0 4.0K 0% /sys/fs/cgroup
none 5.0M 0 5.0M 0% /run/lock
none 5.9G 105M 5.8G 2% /run/shm
none 100M 28K 100M 1% /run/user
/dev/sda2 105G 102G 2.7G 98% /media/sam/System
/dev/sda3 176G 163G 14G 93% /media/sam/Sam //where I'm trying to write
and here is the output of df -i:
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 1523763 552 1523211 1% /dev
tmpfs 1526458 584 1525874 1% /run
/dev/sda5 10362880 4750381 5612499 46% /
none 1526458 2 1526456 1% /sys/fs/cgroup
none 1526458 3 1526455 1% /run/lock
none 1526458 191 1526267 1% /run/shm
none 1526458 26 1526432 1% /run/user
/dev/sda2 3832820 1045155 2787665 28% /media/sam/System
/dev/sda3 35769712 22090147 13679565 62% /media/sam/Sam //where I'm trying to write
I am trying to write files to /media/sam/Sam/. I have tried restarting my machine, unmounting and mounting again but no luck. Also in Java if I create a new file object inside /media/sam/Sam and print the usage information, it prints 0 as below:
File tweetFile = new File( "/media/sam/Sam/" + "test" + ".txt" );
System.out.println( tweetFile.getTotalSpace() ); // prints 0
System.out.println( tweetFile.getFreeSpace()/1000000000 ); // prints 0
System.out.println( tweetFile.getUsableSpace()/1000000000 ); // prints 0
Any help is really appreciated as I'm trying to fix this for the whole day and getting really frustrated.
EDIT
Here is the exact message thrown:
Exception: java.io.IOException: No space left on device
java.io.IOException: No space left on device
at java.io.UnixFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:1006)
at utils.FileUtil.writeToFile(FileUtil.java:64)
at experiments.usinglists.tagbasedeval.ToindexTweetsForAUser.main(ToindexTweetsForAUser.java:36)
In my case the Java Process was operating with a temp-directory, using default java.io.tmpdir (in my case /tmp).
I was expecting it to work in another partition. So maybe changing the default works:
-Djava.io.tmpdir=/media/sam/Sam/tmp

Resolving java.lang.OutOfMemoryError: Java heap space

As the title suggests I'm getting this error inside a thread.
The offending LOCs looks like this:
for (int i = 0; i < objectListSize; i++) {
logger.INFO("Loop repeat: "+i+" ...", true);
final Double discreteScore = sp.getDouble(superPeerSocket);
final int expectedObjectIDs = sp.getInteger(superPeerSocket);
final String discreteObjects[] = new String[expectedObjectIDs];
for ( int j = 0; j < expectedObjectIDs; j++)
discreteObjects[j] = sp.getString(superPeerSocket);
htPlus.attachInitialDiscreteList2L1(discreteScore, discreteObjects);
}
The final String discreteObjects[] declaration is where I get the error. I am running this code inside a thread. I have two threads currently active when I get this. I also tried using the MAT tool from eclipse. here is a link with some chart files inside:
PLC chart files (dropbox URL)
If anyone has any idea for this problem I would be grateful.
P.S.: I am thinking to remove the loop although it just fails in the first loop pass.
(I get this in the output when the program fails)
Expected data size: 10
Repeat: 0 ...
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid3793.hprof ...
Heap dump file created [1404020 bytes in 0.015 secs]
Exception in thread "1" java.lang.OutOfMemoryError: Java heap space
at planetlab.app.factory.Worker$15.run(Worker.java:796)
at java.lang.Thread.run(Thread.java:662)
Something irrelevant:
What's with the code not properly formatted/intended error when making posts in stack overflow? It took me 15 minutes to figure out what to do :# :S :#
Every Java program runs in a sandbox. While your OS might have 10 GB of RAM available to it your app might only have 128 MB.
You need to make sure you app has enough ram allocated to the JVM by using the -Xms -Xmx arguments. -Xms indicates the minimum and -Xmx the maximum
It's been suggested in the comments that your expectedObjectIDs seem kinda high. I would certainly check that out. However, you can use the following code to get an idea as you to memory usage and available memory. Using that info you can adjust your -Xms -Xmx accordingly.
Good luck!
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
System.out.println("free memory: " + freeMemory / 1024);
System.out.println("allocated memory: " + allocatedMemory / 1024);
System.out.println("max memory: " + maxMemory /1024);
System.out.println("total free memory: " +
(freeMemory + (maxMemory - allocatedMemory)) / 1024);

Categories

Resources