Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js-Segfault:11,具有相当大的数组_Javascript_Arrays_Node.js_Segmentation Fault - Fatal编程技术网

Javascript Node.js-Segfault:11,具有相当大的数组

Javascript Node.js-Segfault:11,具有相当大的数组,javascript,arrays,node.js,segmentation-fault,Javascript,Arrays,Node.js,Segmentation Fault,这是第二篇文章,这篇文章真让我抓狂。我有一个函数,它处理数组,试图找到类似的数据。该数组包含1410个元素,我认为它们是很多元素,但没有任何节点或我的计算机不能处理。 我的代码给出了“Segmentation Fault:11”错误,我发现这与内存访问问题有关,所以我甚至想测试我的Mac的RAM,但一切都很好。segfault使调试变得非常困难,这就是我来这里的原因 出现问题的代码在此处: return matchings.map(matchArray => { const names

这是第二篇文章,这篇文章真让我抓狂。我有一个函数,它处理数组,试图找到类似的数据。该数组包含1410个元素,我认为它们是很多元素,但没有任何节点或我的计算机不能处理。

我的代码给出了“Segmentation Fault:11”错误,我发现这与内存访问问题有关,所以我甚至想测试我的Mac的RAM,但一切都很好。segfault使调试变得非常困难,这就是我来这里的原因

出现问题的代码在此处:

return matchings.map(matchArray => {
  const namesList = matchArray
    .map(matchItem => matchItem.name)
    .sort((a, b) => a.localeCompare(b))

  const symbolsList = matchArray
    .map(matchItem => matchItem.symbol)
    .sort((a, b) => a.localeCompare(b))

  return {
    name: common.getMode(namesList),
    symbol: common.getMode(symbolsList),
    matches: matchArray
  }
}).sort((a, b) => a.name.localeCompare(b.name))
其中,
matchings
是我所说的数组
common.getMode(数组)
具有以下代码:

array.sort()

const stats = {
  top: {
    name: '',
    freq: 0
  },
  current: {
    name: array[0],
    freq: 1
  }
}

for (let idxName = 1; idxName < array.length; idxName++) {
  const currentName = array[idxName]
  const lastName = array[idxName - 1]

  if (currentName === lastName) {
    stats.current.freq++
  } else {
    if (stats.current.freq > stats.top.freq) {
      stats.top.name = stats.current.name
      stats.top.freq = stats.current.freq
    }
    stats.current = {
      name: currentName,
      freq: 1
    }
  }
}

if (stats.current.freq > stats.top.freq) {
  stats.top.name = stats.current.name
  stats.top.freq = stats.current.freq
}

return stats.top.name
array.sort()
常数统计={
顶部:{
名称:“”,
频率:0
},
当前:{
名称:数组[0],
频率:1
}
}
for(让idxName=1;idxNamestats.top.freq){
stats.top.name=stats.current.name
stats.top.freq=stats.current.freq
}
stats.current={
姓名:currentName,
频率:1
}
}
}
如果(stats.current.freq>stats.top.freq){
stats.top.name=stats.current.name
stats.top.freq=stats.current.freq
}
return stats.top.name
值得一提的是,当使用较小的数组(1000)执行时,代码运行良好,这让我相信它不是我的代码。在线上也很少有关于节点SEGFULT 11的内容,这是没有帮助的


非常感谢您的任何想法

TL;DR使用从调用堆栈中消除应力

编辑(附说明)

请参阅以了解
调用堆栈
内存堆
队列
之间的区别。尽管对象和变量存在于
land中,但函数调用在
调用堆栈
中引用,您的第二个数据集耗尽了该堆栈(16'000个堆栈帧);因此,您的算法无法跟上,因为它无法继续分配新的函数调用

请参阅,其中指向有关
调用堆栈的更多信息,以及指向获取
堆上数据的方法

原始答案

我可能完全不感兴趣,但我很想看看将循环转换为递归是否有助于内存处理。我想在我的盒子上试一试,但把一切都安排好是件麻烦事

你能试试这个吗?它使用扩展运算符和数组分解,因此您可能需要将babel-preset-stage-0添加到项目和
.babelrc
文件中

Javascript

let common = {};
common.getMode = (arr, compare_fn) => {
  const compare = !!compare_fn ? compare_fn : (a, b) => a.localeCompare(b)
  arr.sort(compare)

  const stats = {
    top: {
      name: '',
      freq: 0
    },
    current: {
      name: arr[0],
      freq: 1
    }
  }

  for (let i=1, imax = arr.length ; i < imax ; ++i) {
    const currentName = arr[i]
    const lastName = arr[i - 1]

    if (currentName === lastName) {
      stats.current.freq++
    } else {
      if (stats.current.freq > stats.top.freq) {
        stats.top.name = stats.current.name
        stats.top.freq = stats.current.freq
      }
      stats.current = {
        name: currentName,
        freq: 1
      }
    }
  }

  if (stats.current.freq > stats.top.freq) {
    stats.top.name = stats.current.name
    stats.top.freq = stats.current.freq
  }

  return stats.top.name
};

const build_prop_list = (prop, input_array, output_array = []) => {
  if(input_array.length == 0) return output_array;
  else {
    const [current, ...tail] = input_array;
    const new_array = [...output_array, current[prop]];
    return build_prop_list(prop, tail, new_array);
  }
}

const work = (input_array, output_array = []) => {
  if(input_array.length == 0) return output_array.sort((a, b) => a.name.localeCompare(b.name));
  else {
    const [matchArray, ...tail] = input_array;

    const namesList = build_prop_list("name", matchArray);
    const symbolsList = build_prop_list("symbol", matchArray);

    const new_element = {
      name: common.getMode(namesList),
      symbol: common.getMode(symbolsList),
      matches: matchArray
    };

    const new_array = [...output_array, new_element];
    return work(tail, new_array);
  }
}

let result = work(insert_your_json_here);

谢谢你的回复。非工作数组的JSON在这里:工作数组在这里:。有没有可能是因为等待承诺超时,因为函数在给出SEGFULT之前大约需要8秒?您似乎已经解决了它,非常感谢。是否存在导致这种情况的节点限制?我在运行代码时监视内存使用情况,内存似乎很好。我认为Node应该能够处理这个问题,不是吗?这叫做尾部调用优化。基本上,从堆栈按其参数的数量成比例增长到应该增长到固定大小的堆栈(取决于在函数内分支或调用其他函数的次数)。我会试着为你参考一些文献。我不认为它依赖于节点。这是一个在任何语言和计算机上都会出现的问题。您还可以在
common.getMode(…)
中优化循环,但是第一次迭代的行为会发生变化。我也会将其作为编辑来编写。请参见和。其思想是不要在函数末尾分支到另一个函数或求值,而是使用递归为您执行循环。如果对你有帮助的话,你也可以对答案进行投票。我已经试着对答案进行投票,这太棒了,但是我的声誉目前还不到15。我明天去看看,因为我太累了。再次感谢Sumi!我回来了,苏米。我已经仔细看过了你的编辑,并对整件事做了大量的研究。我真的很高兴您提供的代码能够正常工作,但是我正在尝试找出SEGFULT的真正原因,因为这将帮助我更好地理解JS和V8。我已经能够确认没有由于记录
new Error.stack
而导致调用堆栈溢出,并且堆栈上只有两到三个调用。我还使用了
process.memoryUsage()
并比较了
heapTotal
heapUsed
,这表明我还有约5MB的堆空间。
  const feed = (input_array) => {
    if(input_array.length == 0) return;
    const [lastName, currentName, ...tail] = input_array;

    if (currentName === lastName) {
      stats.current.freq++
    } else {
      if (stats.current.freq > stats.top.freq) {
        stats.top.name = stats.current.name
        stats.top.freq = stats.current.freq
      }
      stats.current = {
        name: currentName,
        freq: 1
      }
    }

    return feed(tail);
  }(arr);