在node.js流中使用buffer和buffer.toString()时的内存考虑

在node.js流中使用buffer和buffer.toString()时的内存考虑,node.js,buffer,node.js-stream,Node.js,Buffer,Node.js Stream,我正在执行readstream.pipe(transformstream).pipe(writeStream)。使用readstream-->从文件系统读取应用程序xml使用transform stream-->基于不同的标记执行一些操作将其写入另一个文件系统 在transformstream内部的转换操作期间。我正在为每个块执行buffer.toString(),因为我需要在推送字符串之前操作字符串: myTransformStream._transform = function(

我正在执行readstream.pipe(transformstream).pipe(writeStream)。使用readstream-->从文件系统读取应用程序xml使用transform stream-->基于不同的标记执行一些操作将其写入另一个文件系统

在transformstream内部的转换操作期间。我正在为每个块执行buffer.toString(),因为我需要在推送字符串之前操作字符串:

      myTransformStream._transform = function(chunk, encoding, done) {
        var stringTobeManipulated = chunk.toString();
        // perform changes on stringTobeManipulated and push it to writestream
      }
XML的大小可以达到3MB,我注意到我被分成了大约44个块

基于给定的问题,我对v8堆和系统中的内存消耗都有疑问:

1) 我知道缓冲区存储在v8内存之外。在_transform函数中执行chunk.toString()时,它是否在v8内存中创建javascript字符串对象?如果是的话,我假设它在失去所有引用后将被垃圾收集

2) 由于缓冲区是系统内存的一部分,我相信它们不会被垃圾收集,那么什么时候会释放内存呢

3) 当我将每个块转换为字符串时,该应用程序是转换流的一个很好的用例吗

编辑: 可能是我没有解释清楚。无论如何,我一直在试图找到一种方法,在将xml标记转换为json之前从xml标记中删除名称空间。这是我最后得到的代码。利用javascrtipt中的记忆功能。请让我知道你们是否找到更好或更节省内存的方法。我们正在使用actionhero.js框架

var action = {};
var xml2js = require('xml2js');
var fs = require('fs');
/////////////////////////////////////////////////////////////////////
// metadata
action.name = 'removeNamespace';
action.description = 'I will parse the article related xml and yield the result';
action.inputs = {
    'required': [],
    'optional': []
};
action.blockedConnectionTypes = [];
action.outputExample = {
    articleHeading: 'heading',
    articleBody: 'body'
};

/////////////////////////////////////////////////////////////////////
// functional
action.run = function(api, connection, next) {
    var stream = require('stream');
    var removeNamespace = new stream.Transform();
    var util = require('util');
    var output = fs.createWriteStream('output.xml');
    removeNamespace._transform = function(chunk, encoding, done) {
        removeNamespace._transform.brokenTag = removeNamespace._transform.brokenTag || false;
        removeNamespace._transform.brokenString = removeNamespace._transform.brokenString || '';
        var convertedString = chunk.toString().trim();
        if (removeNamespace._transform.brokenTag === true){
                convertedString = removeNamespace._transform.brokenString + convertedString ;
        }
        removeNamespace._transform.brokenTag = false;
        removeNamespace._transform.brokenString = '' ;
        if (convertedString.lastIndexOf('<') > convertedString.lastIndexOf('>') ){
            removeNamespace._transform.brokenString =convertedString.substring(convertedString.lastIndexOf('<'),convertedString.length+1);
            convertedString = convertedString.substring(0,convertedString.lastIndexOf('<')) ;
            removeNamespace._transform.brokenTag = true ;
        }
        convertedString = convertedString.replace(/>\s+</g, '><')        
                                         .replace.replace(/<[A-Za-z]+:/gi, '<')
                                         .replace(/<\/[A-Za-z]+:/gi, '</');
        done(null, convertedString);
    };
    var Writable = stream.Writable;

    function xmlInMemory(keyToXml, options) {
        Writable.call(this, options);
        this[keyToXml] = new Buffer('');
        this._write = function(chunk, encoding, callback) {
            chunk = (Buffer.isBuffer(chunk)) ? chunk : new Buffer(chunk, encoding);
            this[keyToXml] = Buffer.concat([this[keyToXml], chunk]);
            callback();
        };
    }
    util.inherits(xmlInMemory, Writable);
    var source = fs.createReadStream('path/to/your/xmlfile');
    var target = new xmlInMemory('keyToXml');
    source.pipe(removeNamespace).pipe(target);
    target.on('finish', function() {
        var parser = new xml2js.Parser();
        connection.response.xml2js = target.keyToXml.toString();
        next(connection, true);
        parser.parseString(target.keyToXml.toString(), function(err, result) {  
            connection.response.xml2js = result;
            next(connection, true);
         });
    });
};

/////////////////////////////////////////////////////////////////////
// exports
exports.action = action;
var action={};
var xml2js=require('xml2js');
var fs=需要('fs');
/////////////////////////////////////////////////////////////////////
//元数据
action.name='removeNamespace';
action.description='我将解析与文章相关的xml并生成结果';
action.inputs={
“必需”:[],
“可选”:[]
};
action.blockedConnectionTypes=[];
action.outputExample={
文章标题:“标题”,
articleBody:“body”
};
/////////////////////////////////////////////////////////////////////
//功能性
action.run=函数(api、连接、下一步){
var stream=require(‘stream’);
var removeNamespace=new stream.Transform();
var util=require('util');
var output=fs.createWriteStream('output.xml');
removeNamespace.\u transform=函数(块、编码、完成){
removeNamespace._transform.brokenTag=removeNamespace._transform.brokenTag | | false;
removeNamespace._transform.brokernstring=removeNamespace._transform.brokernstring | |'';
var convertedString=chunk.toString().trim();
if(removeNamespace.\u transform.brokenTag==true){
convertedString=removeNamespace.\u transform.brokenString+convertedString;
}
removeNamespace.\u transform.brokenTag=false;
removeNamespace.\u transform.brokenString='';
if(convertedString.lastIndexOf(“”)){
removeNamespace.\u transform.brokenString=convertedString.substring(convertedString.lastIndexOf('