Sherif
Sherif

Reputation: 21

Stack of detached threads never released

I'm running into a situation where threads that I create detachable are not releasing their memory after they have exited.

I have tried creating the threads in the following ways

1-

pthread_attr_setdetachstate(&pthread_attributes, PTHREAD_CREATE_DETACHED);
pthread_create(&thread_id, &pthread_attributes, establish_connection,
               (void *) establish_connection_arguments);

2-

pthread_create(&thread_id, &pthread_attributes, establish_connection,
               (void *) establish_connection_arguments);
pthread_detach(thread_id);

3-

pthread_create(&thread_id, &pthread_attributes, establish_connection,
               (void *) establish_connection_arguments);

void *establish_connection(void *arguments) {
    pthread_detach(pthread_self());
    return NULL;
}

I'm sure the memory is still retained, as pmap confirms this.

Is it normal behavior, that pmap will still show the threads with their memory after the threads have completed?

Upvotes: 2

Views: 290

Answers (3)

David Schwartz
David Schwartz

Reputation: 182885

The pmap program is showing you the process' memory map. That memory is still used by the process. For example, if another thread is created, that memory might be used for its stack.

Upvotes: 0

Puppy
Puppy

Reputation: 147036

Most likely, the space is cached by whatever memory allocator is in use. Running the odd thread and not having the memory use go down afterwards is not a sign of a leak - you'd have to repeatedly open and close a lot of threads, then check process memory use.

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215597

By default, glibc/nptl caches thread stacks to reuse them. This incurs a small cost of synchronization to add/remove elements from the cache list and a nontrivial (but hopefully not huge) memory cost, but avoids the cost of calling mmap and munmap every time a thread is created or destroyed. I don't suspect there's any way to change this default behavior without extremely fragile hacks.

Edit: Since you said that joinable threads are being released, here's my second guess at the reason: It's very difficult for the implementation to make a thread release its own stack, since it would have no stack to run on while performing the work to release its stack. It's possible to work around this limitation by writing asm that does not need a stack to perorm the munmap syscall immediately followed by self-termination, but I've never seen an implementation do it.

Upvotes: 1

Related Questions