Edd
Edd

Reputation: 107

Java thread memory calculation

Is it possible to calculate memory consumption for each thread? Suppose I divided my task into 4 threads then I want to know how much memory consumption by each threads? I need it to know average and peak memory usage from my threads.

Upvotes: 7

Views: 12903

Answers (3)

gaoagong
gaoagong

Reputation: 1255

You could use Native Memory Tracking to get info about the threads in general, but I'm not sure how to get info about each thread individually.

Add -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics to your vm options when starting your application:

java -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -jar myjar.jar

Now, if you run:

$jps -l

to find the java process on your machine and then

$jcmd <PID> VM.native_memory

you will see something like the following:

Native Memory Tracking:

Total: reserved=2344374KB +4399KB, committed=567362KB +19659KB
...
- Thread (reserved=87894KB, committed=19126KB +756KB)
         (thread #159)
         (stack: reserved=87132KB, committed=18364KB +756KB)
         (malloc=577KB #956)
         (arena=184KB #316)
...

With this info you could do 19126KB/159=120KB to get an average committed size of memory for each thread. The problem is this won't tell you each thread individually and some threads will be larger and others smaller.

You can also use:

$jcmd <PID> VM.native_memory baseline
$jcmd <PID> VM.native_memory summary.diff

This would tell you the difference between a baseline instant of time and a run that you could do during peak traffic.

One word of caution: Enabling NMT has some additional overhead associated with it. You may want to weigh the risks of running an application in PROD with that enabled.

Upvotes: 2

Basil Bourque
Basil Bourque

Reputation: 340060

As others noted, most objects live on the heap. That heap memory is shared across threads. So there is no way to identify which threads are responsible for the size of the heap.

But threads do get their own chunk of memory: the stack.

Stack size

As I recall from presentations by Ron Pressler of Oracle in 2020…

Conventional threads

Each thread is assigned a certain amount of memory for its stack. Since currently threads in Java implementations based on OpenJDK are mapped one-to-one to host OS’ thread, the stack size is arbitrarily set to something like a meg. More memory may be allocated if needed, but is not reduced.

Virtual threads

The plot thickens with virtual threads (fibers) proposed in Project Loom.

Project Loom adds new capabilities to the Java concurrency facilities. As part of this, virtual threads are mapped many-to-one to host OS threads (a.k.a. platform/kernel threads). The JVM will manage these virtual threads rather than the OS, “parking” a virtual thread when its code blocks to allow time for another virtual thread to run via execution time assigned to the “real” platform/kernel thread. The scheduling of that “real” platform/kernel thread to actually get work done on the CPU core is controlled by the host OS, with or without Project Loom (at least in Java implementations based on OpenJDK).

➥ As part of this JVM-management of virtual threads, each virtual thread's stack will start out much smaller. And each stack will grow, and shrink(!), as needed.

Because of this efficient use of both CPU and memory, virtual threads are dramatically "cheaper". So we can run more of them. Even millions of virtual threads are possible on common hardware.

Upvotes: 7

papaya
papaya

Reputation: 1535

Summing up my comment, threads use shared memory. Hence no thread owns any data of it's own apart from the reserved stack memory (which is set during jvm startup).

Since you are focussing on the exact heap size a thread consumes whilst running your jvm, you can simply rather use a memory profiler like visualvm to look at the classes & Objects which your thread creates and assume the consumption size.

You can also ThreadLocal variables to define Objects belonging to a specific thread. This can also help you get the exact memory consumption on a per thread basis.

You can also look at ThreadMXBean, however this is no longer available in the latest jvms.

Upvotes: 2

Related Questions