It's always tempting to allocate objects on the stack, but there's a good reason why you shouldn't allocate large ones if you care about your application's memory footprint: the stack space you use is used forever, even if you don't need it anymore.

Now you might be wondering, wait a sec, I thought that stack variables are freed when they go out of scope, right? Well, yes and no. Let's talk about this. 🧵 1/8

When you allocate an object on the stack two things are going to happen: the visible one is that the stack pointer will be bumped to make space for your object, the invisible one is that physical memory will be allocated for the object if there's not enough room already.

That is, stacks grow dynamically both in terms of address space (the pointer gets bumped) and in terms of physical memory (pages are allocated to back the address space occupied by the stack). 2/8

Show thread

The problem is, when deallocating frames only the visible change happens: the stack pointer gets moved back to the previous frame, but the physical memory that has been occupied is not freed. And here lies the problem.

If you've got a ~100 deep stack, chances are it only takes 10-30 KiB of physical memory. But if you had allocated a 256 KiB buffer on the stack, at any point in the past, then your stack takes at least that amount and always will. 3/8

Show thread

From the operating system's POV that area of memory contains some data you wrote to it and that's the only copy of that data. They're "dirty" in VM speech. So they'll be kept around until the region that holds them gets unmapped (typically when the thread exits and the stack gets deallocated). 4/8

Show thread

This is not a problem with heap-allocated memory because calling free() or delete is telling the allocator that you don't need that data anymore. And the allocator might decide to unmap it entirely or at least discard the physical pages using a mechanism such as `madvise(..., MADV_DONTNEED)` or `VirtualFree(..., MEM_DECOMMIT)` 5/8

Show thread

So think twice before allocating large stuff on the stack, even if you know it'll fit in the maximum stack size (which is quite generous nowadays, 1 MiB on Windows and 8 MiB on Linux IIRC).

If enough active threads do it you might end up with a significant amount of physical memory tied up storing data that you don't care about anymore.

For example, Firefox can easily reach 150 active threads, at 256 KiB apiece that'd be ~40 MiB of RAM. 6/8

Show thread
Follow

@gabrielesvelto
> Firefox can easily reach 150 active threads
Bring back the option to turn e10s off 😂

@m0xee I was thinking only about the main process which has the largest number... my currently open Firefox with ~30 tabs has 1320 active threads across 47 processes.

@gabrielesvelto
That was a joke — I may not always like the architectural changes in FF, but I have to admit, it's really well optimized the way it is now — to the point that it performs better than Palemoon, which was forked before FF got Electrolysis (I think🤔), even on anemic machines with single-core 32-bit CPUs, such as old Thinkpad T43 with Pentium-M that I have.
Even with no SMP or SMT Firefox might get slow, but remains responsive, while Palemoon fails to even redraw its UI at times.

sup dat wat do copa dat dude dat poom boo muh fuggin wad da dood tomad do watta do muhhfugga bix nood wuttbba bubba mo do doaad bix wubba da do did bix nood coppa dat muthafucka wabba dat dude muthfucking cop ho ass muthafucka coppa dat homo nigger wahat dat dude muthafucka bix nood coppa that ho that dude that muthafucking hoe ass nigga mutha fucka wabba dat dood mutha fucka dat nigga bix nood po muh gib dat tum muha fuggin bix nood cosbon :pepe_faggot_a:
Sign in to participate in the conversation
Librem Social

Librem Social is an opt-in public network. Messages are shared under Creative Commons BY-SA 4.0 license terms. Policy.

Stay safe. Please abide by our code of conduct.

(Source code)

image/svg+xml Librem Chat image/svg+xml