I need to handle the large array of mpz_t
and release the memory afterwords. However, when profiling the RSS at each stage with htop
command, mpz_clear
does not seem to free the memory completely.
Here's the sample C code:
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
int main(void) {
mpz_t *A;
int size = 1<<20;
A = (mpz_t *) malloc(size*sizeof(mpz_t));
getchar(); // RSS=876KB
for (int i=0; i<size; i++) {
mpz_init_set_ui(A[i],0);
}
getchar(); // RSS=50MB
for (int i=0; i<size; i++) {
mpz_clear(A[i]);
}
free(A);
getchar(); // RSS=34MB!!
return 0;
}
Looking at the answer here, the memory deallocation process above (i.e. call mpz_clear
on mpz_t
elements & free
array) is properly done.
I also tried with the vector of mpz_class
C++ wrapper as follows, which resulted in the same situation.
#include <gmpxx.h>
#include <iostream>
#include <vector>
int main(void) {
std::vector<mpz_class> A;
int size = 1 << 20;
A.reserve(size);
std::cin.ignore();
for (int i=0; i<(size); i++) {
A.emplace_back(0);
}
std::cin.ignore();
std::vector<mpz_class>().swap(A);
std::cin.ignore();
return 0;
}
Is there any way to release the whole memory allocated for an mpz_t
array?
Update
Thanks to the comment section I've learnt that free
does not necessarily release the memory back to the OS. But in my case, using glibc on Ubuntu 16.04, free()
does release the amount of memory reserved by malloc
(i.e 16*2^20 = 16MB, assuming that sizeof(mpz_t)
is 16-byte) because it exceeds the default M_MMAP_THRESHOLD
value (=128KB).
So I suspect that there is still some orphaned memory implicitly allocated by GMP (≈32MB in the above example) and free()
needs to be called on it separately.