почему emscripten кажется утечкой памяти для этого кода - PullRequest
0 голосов
/ 11 сентября 2018

Я работал над этим в течение нескольких дней, но не могу найти причину. Я пишу код c "1.c", затем компилирую его в 1.js и 1.wasm. Затем я пишу 2.js для вызова 1.js и 3.js для вызова 2.js. Но когда я запускаю 3.js, объем памяти превышает 2 ГБ (она должна быть меньше 500 МБ), и память со временем увеличивается. Я использую heapdump, и он показывает, что общее количество кучи невелико, но rss превышает 1,5 ГБ. Я неоднократно проверял свой код , и я думаю, что освободил память.

это мой код. <1.c> Я использую

emcc  -s WASM=1  -s BINARYEN_ASYNC_COMPILATION=0 -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_NAME="WASMModule" -s EXPORTED_FUNCTIONS="['_test_string_1','_malloc','_free']" -s  EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap","getValue","stringToUTF16","UTF16ToString"]'  -s MODULARIZE=1 -s 'EXPORT_NAME="MyWASMCode"' 1.c -o 1.js

для компиляции 1.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *test_string_1(const void *s1, int len1, const void *s2, int len2,int* out_len,int* statuscode);

void *test_string_1(const void *s1, int len1, const void *s2, int len2,int* out_len,int* statuscode) {
  void *out = malloc(len1 + len2);
  memcpy(out, s1, len1);
  memcpy(out + len1, s2, len2);
  *out_len=len1+len2;
  *statuscode=0;
  return out;
}

int main() {
  char *s1 = "hello";
  char *s2 = "world";
  int out_len=0;
  int statuscode=-1;
  char *s3 = test_string_1(s1, 5, s2, 6,&out_len,&statuscode);
  printf("%s\n%d\n%d\n", s3,out_len,statuscode);
  free(s3);
  return 0;
}

<2.js>

const MyWASMCode=require('./1.js')
let wasminstance=MyWASMCode()


function test1(str1,str2){
  let ret3= wasminstance.then(function(WASMModule){
      let buffer1 = WASMModule._malloc(str1.length*2);
      let buffer2 = WASMModule._malloc(str2.length*2);
      let p_out_len = WASMModule._malloc(4);
      let p_statuscode = WASMModule._malloc(4);

      WASMModule.stringToUTF16( str1, buffer1, str1.length*2+2);
      WASMModule.stringToUTF16( str2, buffer2, str2.length*2+2);
   let result = WASMModule._test_string_1(buffer1,str1.length*2,buffer2,str2.length*2,p_out_len,p_statuscode);
   let out_len= WASMModule.getValue(p_out_len, 'i32')
   let statuscode= WASMModule.getValue(p_statuscode, 'i32')

   let  result2=WASMModule.UTF16ToString(result);

   WASMModule.my_result=result2

   WASMModule._free(result);
   WASMModule._free(buffer1);
   WASMModule._free(buffer2);
   WASMModule._free(p_out_len);
   WASMModule._free(p_statuscode);
   // }
  })
  return ret3.my_result;
}

module.exports={test1};

<3.js>

const fs = require('fs');
const test=require('./2.js');

/*
a.txt and b.txt is both 100000 lines,and a.txt is 150m and b.txt is 50m
*/
let lines1 = fs.readFileSync('./a.txt', 'utf-8')
    .split('\n')
    .filter(Boolean);
let lines2 = fs.readFileSync('./b.txt', 'utf-8')
    .split('\n')
    .filter(Boolean);

for(let j=0;j<10;j++){
  for(let i=0;i<100000;i++){
    let ret_3=test.test1(lines1[i],lines2[i]);
    }
}

когда я запускаю 3.js enter image description here

и память увеличивается, когда j больше. и куча свалок: enter image description here это утечка памяти? или есть проблема с моим кодом?

1 Ответ

0 голосов
/ 13 сентября 2018

Переполнение буфера уничтожает данные, используемые для malloc / free.

  // N*UTF-16 string + a null terminator
  let buffer1 = WASMModule._malloc(str1.length*2+2);
  let buffer2 = WASMModule._malloc(str2.length*2+2);
...