Why do Java 21 virtual threads need less memory than platform threads?

359 Views Asked by At

I do understand that platform threads are expensive as it needs more memory and it's prone to CPU context switching.

But in case of virtual threads where an unimaginably large number of virtual threads can be served by a handful of platform threads, doesn't the virtual threads still need memory space to passivate the context/stack and then attach it to the carrier thread?

How does it make a difference in terms of memory?

Why doesn't spinning 10000 virtual threads die out of memory while 10000 platform thread does?

Both of them need the same stack? And the context where the application related information need to be maintained, right?

Is there any extra overhead in the memory that's only applicable to the platform threads and this is the reason why we say virtual threads are "lighter" in memory? If so what's that that makes this difference?

2

There are 2 best solutions below

0
Louis Wasserman On

Are there any extra overhead in the memory that's only applicable to the platform threads

Yes. A very large amount: megabytes versus kilobytes, if even that much.

This is why virtual threads are considered very cheap in comparison.

5
Solomon Slow On

Both of them need the same stack.

Not true. In fact, that's probably the main "win" of virtual threads.

The call stack of a platform thread always must be contained within a dedicated, contiguous chunk of virtual memory--often around one megabyte, but you can specify larger if needed. That's how it works on every operating system. That's how it has always worked, ever since the idea of "call stack" was invented.

If you haven't done a careful analysis to determine exactly how much memory each of your threads really needs to hold its stack in the very deepest call, then you probably are over-allocating, just to be "on the safe side." Maybe you are over-allocating by orders of magnitude. Of course, it's only virtual memory, so if your program only has a few threads, no problem. But if you want to have thousands of virtual threads,... Suddenly, problem.

I don't actually know how the call stacks of java virtual threads are implemented, but I know that it is not in a single, contiguous allocation per thread.* So, at any given moment in time, no virtual thread has any more memory reserved for its stack than it actually needs.

*If I were implementing it, I imagine I would keep it in a linked list of heap-allocated objects. Maybe each activation record would be its own object, with a next field that points to the caller's activation record. Or maybe, it would be more efficient if it were allocated in larger "chunks." I wouldn't know until I tried.