内存泄漏 Valgrind 不报告但代码使用了太多内存
Memory leak Valgrind doesn't report but code using so much memory
我最近发布了一个分段错误问题,我在 运行 Valgrind 时在我的代码中遇到了这个问题,但是我已经摆脱了分段错误问题,现在代码是 运行 ning,但是“吃”了这么多内存,这表明 valgrind 不一定看到某处的内存泄漏?我真的不确定。例如,它将 运行 在内核终止我的进程之前的第 40 次迭代。
如果我 运行 对代码进行更正的代码:(初始化我的数组并将数组的大小更改为足够大)
char save [16] = {0};
snprintf(save, 16, "%d", saveNum);
const char *type = " .txt";
char Nfilename[16] = {0};
strcat(Nfilename, "N");
strcat(Nfilename, save);
char KEfilename[16] = {0};
strcat(KEfilename, "KE");
strcat(KEfilename, save);
char KIfilename[16] = {0};
strcat(KIfilename, "KI");
strcat(KIfilename, save);
char Pfilename[16] = {0};
strcat(Pfilename, "P");
strcat(Pfilename, save);
print2DArrf(Nfilename, N);
print2DArrf(KEfilename, KE);
print2DArrf(KIfilename, KI);
print2DArrf(Pfilename, P);
这解决了我在每次精确迭代时遇到的分段错误问题。但是,如果我 运行 几次迭代的代码,我的计算机将 运行 内存不足,我尝试 运行 将代码与 activity 内存监视器 Mac(因为 Valgrind 在调试模式下 运行 需要几天时间,并且没有内存泄漏问题),结果是代码在几分钟内达到 16GB!我确保释放了所有东西,所以一定有其他事情发生了。
我想知道发生了什么,为什么它在代码中占用了这么多内存以及如何修复它?我想查看代码中的每一个主要功能(如下所示),然后 运行 分别查看每个功能以查明问题所在,但这似乎很乏味,可能并没有真正的帮助。真的是内存泄漏吗?
这些是我一直在寻求 运行 解决此“内存”问题的主要功能:
// calculate some values
convolution(Nk, KEk, Pek);
Fourier3D(Pek, kb, Pek);
convolution(Nk, KIk, Pik);
Fourier3D(Pik, kb, Pik);
Freqk(Nk, KIk,KEk , kb, eps0, mi, me, ri, rn, nn, Oci, Oce, e, nuink, nuiek, nuiik, nuenk, nueek, nueik, isigPk, NNk);
dk(Nk, kx, dndxk);
dk(Nk, ky, dndyk);
calcPSk(dndxk, dndyk, Pik, Pek, nuink, nuiek, nuenk, nueik, isigPk, Oci, Oce, u, B, ksqu, potSourcek);
主要代码示例:
#include<math.h>
#include<stdio.h>
#include "Functions.h"
#include "fftw3.h"
#include <cstring>
int main(){
// Setting parameters
double frequency = 200.0;
double dt = 0.1;
double tend = 5000.;
double err_max = 1e-7;
int P_iter_max = 500;
int iter_max = tend / dt;
int saveNumber = 1;
//Initialize Parameters
double *N;
N = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Nk;
Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex));
double *KIk;
KIk = (double*) fftw_malloc(nx*ny*sizeof(double));
double *KE;
KE = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *KEk;
KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
double *P;
P = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Pk;
Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
//Save I.Cs
int P_iter = Potk(invnk, dndxk, dndyk, Pk, PSk, kx, ky, ninvksq, err_max, P_iter_max);
for (int iter = 0; iter < iter_max; iter++){
// calculate some values
convolution(Nk, KEk, Pek);
Fourier3D(Pek, kb, Pek);
convolution(Nk, KIk, Pik);
Fourier3D(Pik, kb, Pik);
Freqk(Nk, KIk,KEk , kb, eps0, mi, me, ri, rn, nn, Oci, Oce, e, nuink, nuiek, nuiik, nuenk, nueek, nueik, isigPk, NNk);
dk(Nk, kx, dndxk);
dk(Nk, ky, dndyk);
calcPSk(dndxk, dndyk, Pik, Pek, nuink, nuiek, nuenk, nueik, isigPk, Oci, Oce, u, B, ksqu, potSourcek);
//Check for convergence
// Save I.C loop
P_iter = Pk(NNk, dndxk, dndyk, phik, potSourcek, kx, ky, ninvksqu, err_max, P_iter_max);
} // seems to be the correct location of for loop end (see comment)
double time[iter_max + 1];
time[0] = 0;
c2rfft(Nk, N);
c2rfft(KEk, KE);
c2rfft(KIk, KI);
c2rfft(Pk, P);
char Ninitial[] = "N_initial.txt";
char KEinitial[] = "KE_initial.txt";
char KIinitial[] = "KI_initial.txt";
char Pinitial[] = "P_initial.txt";
print2DArrf(Ninitial, N);
print2DArrf(KEinitial, KE);
print2DArrf(KIinitial, KI);
print2DArrf(Pinitial, P);
} // close of main() (??)
我非常感谢您提供有关如何解决此问题的一些见解。我是新手,我发现理解这个问题有些困难。
确保从堆中释放()所有分配的内存
double *N;
N = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Nk;
Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex));
double *KIk;
KIk = (double*) fftw_malloc(nx*ny*sizeof(double));
double *KE;
KE = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *KEk;
KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
double *P;
P = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Pk;
Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
.
.
.
free(N);
free(Nk);
free(KIk);
free(KE);
free(KEk);
free(P);
free(Pk);
根据 valgrind
,我假设您指的是使用 memcheck
工具。 memcheck
只有当你在执行结束时没有释放它时才会认为是泄漏。
在不知道卷积和傅里叶变换细节的情况下,您可以使用 valgrind
的 massif
工具分析程序的内存使用情况。您可以获得一系列快照并查看您的 out-of-control 内存来自何处。
我最近发布了一个分段错误问题,我在 运行 Valgrind 时在我的代码中遇到了这个问题,但是我已经摆脱了分段错误问题,现在代码是 运行 ning,但是“吃”了这么多内存,这表明 valgrind 不一定看到某处的内存泄漏?我真的不确定。例如,它将 运行 在内核终止我的进程之前的第 40 次迭代。
如果我 运行 对代码进行更正的代码:(初始化我的数组并将数组的大小更改为足够大)
char save [16] = {0};
snprintf(save, 16, "%d", saveNum);
const char *type = " .txt";
char Nfilename[16] = {0};
strcat(Nfilename, "N");
strcat(Nfilename, save);
char KEfilename[16] = {0};
strcat(KEfilename, "KE");
strcat(KEfilename, save);
char KIfilename[16] = {0};
strcat(KIfilename, "KI");
strcat(KIfilename, save);
char Pfilename[16] = {0};
strcat(Pfilename, "P");
strcat(Pfilename, save);
print2DArrf(Nfilename, N);
print2DArrf(KEfilename, KE);
print2DArrf(KIfilename, KI);
print2DArrf(Pfilename, P);
这解决了我在每次精确迭代时遇到的分段错误问题。但是,如果我 运行 几次迭代的代码,我的计算机将 运行 内存不足,我尝试 运行 将代码与 activity 内存监视器 Mac(因为 Valgrind 在调试模式下 运行 需要几天时间,并且没有内存泄漏问题),结果是代码在几分钟内达到 16GB!我确保释放了所有东西,所以一定有其他事情发生了。
我想知道发生了什么,为什么它在代码中占用了这么多内存以及如何修复它?我想查看代码中的每一个主要功能(如下所示),然后 运行 分别查看每个功能以查明问题所在,但这似乎很乏味,可能并没有真正的帮助。真的是内存泄漏吗?
这些是我一直在寻求 运行 解决此“内存”问题的主要功能:
// calculate some values
convolution(Nk, KEk, Pek);
Fourier3D(Pek, kb, Pek);
convolution(Nk, KIk, Pik);
Fourier3D(Pik, kb, Pik);
Freqk(Nk, KIk,KEk , kb, eps0, mi, me, ri, rn, nn, Oci, Oce, e, nuink, nuiek, nuiik, nuenk, nueek, nueik, isigPk, NNk);
dk(Nk, kx, dndxk);
dk(Nk, ky, dndyk);
calcPSk(dndxk, dndyk, Pik, Pek, nuink, nuiek, nuenk, nueik, isigPk, Oci, Oce, u, B, ksqu, potSourcek);
主要代码示例:
#include<math.h>
#include<stdio.h>
#include "Functions.h"
#include "fftw3.h"
#include <cstring>
int main(){
// Setting parameters
double frequency = 200.0;
double dt = 0.1;
double tend = 5000.;
double err_max = 1e-7;
int P_iter_max = 500;
int iter_max = tend / dt;
int saveNumber = 1;
//Initialize Parameters
double *N;
N = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Nk;
Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex));
double *KIk;
KIk = (double*) fftw_malloc(nx*ny*sizeof(double));
double *KE;
KE = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *KEk;
KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
double *P;
P = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Pk;
Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
//Save I.Cs
int P_iter = Potk(invnk, dndxk, dndyk, Pk, PSk, kx, ky, ninvksq, err_max, P_iter_max);
for (int iter = 0; iter < iter_max; iter++){
// calculate some values
convolution(Nk, KEk, Pek);
Fourier3D(Pek, kb, Pek);
convolution(Nk, KIk, Pik);
Fourier3D(Pik, kb, Pik);
Freqk(Nk, KIk,KEk , kb, eps0, mi, me, ri, rn, nn, Oci, Oce, e, nuink, nuiek, nuiik, nuenk, nueek, nueik, isigPk, NNk);
dk(Nk, kx, dndxk);
dk(Nk, ky, dndyk);
calcPSk(dndxk, dndyk, Pik, Pek, nuink, nuiek, nuenk, nueik, isigPk, Oci, Oce, u, B, ksqu, potSourcek);
//Check for convergence
// Save I.C loop
P_iter = Pk(NNk, dndxk, dndyk, phik, potSourcek, kx, ky, ninvksqu, err_max, P_iter_max);
} // seems to be the correct location of for loop end (see comment)
double time[iter_max + 1];
time[0] = 0;
c2rfft(Nk, N);
c2rfft(KEk, KE);
c2rfft(KIk, KI);
c2rfft(Pk, P);
char Ninitial[] = "N_initial.txt";
char KEinitial[] = "KE_initial.txt";
char KIinitial[] = "KI_initial.txt";
char Pinitial[] = "P_initial.txt";
print2DArrf(Ninitial, N);
print2DArrf(KEinitial, KE);
print2DArrf(KIinitial, KI);
print2DArrf(Pinitial, P);
} // close of main() (??)
我非常感谢您提供有关如何解决此问题的一些见解。我是新手,我发现理解这个问题有些困难。
确保从堆中释放()所有分配的内存
double *N;
N = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Nk;
Nk = (fftw_complex*) fftw_malloc(nx*nyk*sizeof(fftw_complex));
double *KIk;
KIk = (double*) fftw_malloc(nx*ny*sizeof(double));
double *KE;
KE = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *KEk;
KEk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
double *P;
P = (double*) fftw_malloc(nx*ny*sizeof(double));
fftw_complex *Pk;
Pk = (fftw_complex*) fftw_malloc(nx*nyk* sizeof(fftw_complex));
.
.
.
free(N);
free(Nk);
free(KIk);
free(KE);
free(KEk);
free(P);
free(Pk);
根据 valgrind
,我假设您指的是使用 memcheck
工具。 memcheck
只有当你在执行结束时没有释放它时才会认为是泄漏。
在不知道卷积和傅里叶变换细节的情况下,您可以使用 valgrind
的 massif
工具分析程序的内存使用情况。您可以获得一系列快照并查看您的 out-of-control 内存来自何处。