Tracking Threads Memory and CPU Consumption

Finding usage of resources (CPU and memory) by threads of a process in unix (solaris/linux)

You could use the ps command with some option:


ps -eLo pid,ppid,lwp,nlwp,osz,rss,ruser,pcpu,stime,etime,args | more
PID PPID LWP NLWP SZ RSS RUSER %CPU STIME ELAPSED COMMAND
0 0 1 1 0 0 root 0.0 Oct_02 4-02:13:37 sched
1 0 1 1 298 528 root 0.0 Oct_02 4-02:13:36 /sbin/init
2 0 1 1 0 0 root 0.0 Oct_02 4-02:13:36 pageout

Have a look at the ps man's page to get some information (LWP (light weight process))

Tracking CPU and Memory usage per process

Press Win+R, type perfmon and press Enter. When the Performance window is open, click on the + sign to add new counters to the graph. The counters are different aspects of how your PC works and are grouped by similarity into groups called "Performance Object".

For your questions, you can choose the "Process", "Memory" and "Processor" performance objects. You then can see these counters in real time

You can also specify the utility to save the performance data for your inspection later. To do this, select "Performance Logs and Alerts" in the left-hand panel. (It's right under the System Monitor console which provides us with the above mentioned counters. If it is not there, click "File" > "Add/remove snap-in", click Add and select "Performance Logs and Alerts" in the list".) From the "Performance Logs and Alerts", create a new monitoring configuration under "Counter Logs". Then you can add the counters, specify the sampling rate, the log format (binary or plain text) and log location.

Throttling CPU/Memory usage of a Thread in Java?

If I understand your problem, one way would be to adaptively sleep the threads, similarly as video playback is done in Java. If you know you want 50% core utilization, the your algorithm should sleep approximately 0.5 seconds - potentially distributed within a second (e.g. 0.25 sec computation, 0.25 sec sleep, e.t.c.). Here is an example from my video player.

long starttime = 0; // variable declared
//...
// for the first time, remember the timestamp
if (frameCount == 0) {
starttime = System.currentTimeMillis();
}
// the next timestamp we want to wake up
starttime += (1000.0 / fps);
// Wait until the desired next time arrives using nanosecond
// accuracy timer (wait(time) isn't accurate enough on most platforms)
LockSupport.parkNanos((long)(Math.max(0,
starttime - System.currentTimeMillis()) * 1000000));

This code will sleep based on the frames/second value.

To throttle the memory usage, you could wrap your object creation into a factory method, and use some kind of semaphore with a limited permits as bytes to limit the total estimated object size (you need to estimate the size of various objects to ration the semaphore).

package concur;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class MemoryLimited {
private static Semaphore semaphore = new Semaphore(1024 * 1024, true);
// acquire method to get a size length array
public static byte[] createArray(int size) throws InterruptedException {
// ask the semaphore for the amount of memory
semaphore.acquire(size);
// if we get here we got the requested memory reserved
return new byte[size];
}
public static void releaseArray(byte[] array) {
// we don't need the memory of array, release
semaphore.release(array.length);
}
// allocation size, if N > 1M then there will be mutual exclusion
static final int N = 600000;
// the test program
public static void main(String[] args) {
// create 2 threaded executor for the demonstration
ExecutorService exec = Executors.newFixedThreadPool(2);
// what we want to run for allocation testion
Runnable run = new Runnable() {
@Override
public void run() {
Random rnd = new Random();
// do it 10 times to be sure we get the desired effect
for (int i = 0; i < 10; i++) {
try {
// sleep randomly to achieve thread interleaving
TimeUnit.MILLISECONDS.sleep(rnd.nextInt(100) * 10);
// ask for N bytes of memory
byte[] array = createArray(N);
// print current memory occupation log
System.out.printf("%s %d: %s (%d)%n",
Thread.currentThread().getName(),
System.currentTimeMillis(), array,
semaphore.availablePermits());
// wait some more for the next thread interleaving
TimeUnit.MILLISECONDS.sleep(rnd.nextInt(100) * 10);
// release memory, no longer needed
releaseArray(array);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
// run first task
exec.submit(run);
// run second task
exec.submit(run);
// let the executor exit when it has finished processing the runnables
exec.shutdown();
}
}

Huge Memory and CPU usage with Multi-threading

You don't say how you're starting the threads, but it sounds like you're creating a thread (i.e. new Thread(...) and starting it. If that's the case, you're creating hundreds or possibly thousands of threads, each of which is trying to load a song and verify it. This causes some serious problems:

  1. Having all those songs in memory at one time will very likely cause you to run out of memory.
  2. With hundreds of threads, the computer spends a lot of time doing thread context switches, letting thread 1 run for a bit, then thread 2, then 3, etc. It's quite possible that your computer is thrashing--spending more time doing thread context switches than doing actual work.
  3. The disk drive from which you're loading files can only do one thing at a time. If two threads ask to load a file, one of them will have to wait. Because reading the file probably takes longer than any processing, it's unlikely that having multiple threads doing this work is gaining you much.

Your design is seriously over-complicated. You can simplify it, reduce your memory requirements, and probably increase your processing speed by using a single thread. But if one thread is two slow, you probably want no more than three:

One thread (the main thread) gets the file names, checks them, and places them on a queue. This is step 1 on your list.

Two consumer threads read the queue and do the rest of the processing. Each of these consumer threads waits on the queue and performs step 4 (loading the file, doing the processing, and adding the result to a list).

This kind of thing is incredibly easy to do with a BlockingCollection, which is a concurrent queue. The basic idea is:

// this is the output list
List<MusicRecord> ProcessedRecords = new List<MusicRecord>();
object listLock = new object(); // object for locking the list when adding

// queue of file names to process
BlockingCollection<string> FilesToProcess = new BlockingCollection<string>();

// code for main thread

// Start your consumer threads here.

List<string> filesList = GetFilesListFromOpenDialog(); // however you do this
foreach (string fname in filesList)
{
if (IsGoodFilename(fname))
{
string fullPath = CreateFullPath(fname);
FilesToProcess.Add(fullPath); // add it to the files to be processed
}
}
// no more files, mark the queue as complete for adding
// This marks the "end of the queue" so that clients reading the queue
// know when to stop.
FilesToProcess.CompleteAdding();

// here, wait for threads to complete

The code for your threads is pretty simple:

foreach (var fname in FilesToProcess.GetConsumingEnumerable())
{
// Load file and process it, creating a MusicRecord
// Then add to output
lock (listLock)
{
ProcessedRecord.Add(newRecord);
}
}

That's all the thread needs to do. The GetConsumingEnumerable handles waiting (non-busy) on the queue, de-queueing an item, and exiting when the queue is known to be empty.

With this design, you can start with a single consumer thread and scale up to as many as you need. However, it won't make sense to have more threads than you have CPU cores, and as I said before the limiting factor will quite likely be your disk drive.



Related Topics



Leave a reply



Submit