我目前正致力于以下要求。 这是要求:在服务器端,大文件被分成4000字节块(帧)。每个块依次压缩(使用zlib)并发送到客户端进程。例如,如果文件大小为12000字节,则将其分为3个块。
上面的文件将有3个块=> Block-1 Block-1 Block-0
收到后,客户端解压缩每个块(或帧)并写入堆上分配的缓冲区。当客户端收到与整个文件对应的所有块时,生成的文件的未压缩版本将写入磁盘。
我编写了一个例程inflateData,根据收到的块#
执行以下操作收到第一个街区时, - inflateInit - 膨胀 - inflateReset 当收到中间块时, - 膨胀 - inflateReset 收到最后一个块时 - 膨胀 - inflateEnd
通过上述例程,块的解压缩按预期发生。但是我面临的问题是它消耗了大量内存,并且在某些时候整个系统都会变慢。使用valgrind检查时,会报告inflateInit2_的内存泄漏。这会导致系统资源耗尽。
== 30359 == 6个街区中的57,312个字节可能在67个损失记录中丢失
== 30359 ==在0x4A069EE:malloc(vg_replace_malloc.c:270)
== 30359 == by 0x3E57808F1E:inflateInit2_(in /lib64/libz.so.1.2.3)
== 30359 == by 0x40C220:inflateData(productMaker.c:1668)
以下是例程inflateData。
int inflateData(
char* const inBuf,
unsigned long inLen,
unsigned int isFirstBlk,
unsigned int isLastBlk,
const char* outBuf,
unsigned long* outLen)
{
int have;
int readsz;
int bsize;
static z_stream zstrm;
int zerr;
int flush;
char out[CHUNK_SZ];
char in[CHUNK_SZ];
int ret,nwrite,idx = -1;
int savedByteCntr=0;
unsigned char *dstBuf;
int firstCall = 1;
int totalBytesIn=0;
int inflatedBytes=0;
int decompByteCounter = 0;
int num=0;
ret = Z_OK;
readsz = 0;
bsize = CHUNK_SZ;
dstBuf = (unsigned char *) outBuf;
if(isFirstBlk){
memset(&zstrm, '\0', sizeof(z_stream));
zstrm.zalloc = Z_NULL;
zstrm.zfree = Z_NULL;
zstrm.opaque = Z_NULL;
if ((zerr = inflateInit(&zstrm)) != Z_OK) {
uerror("ERROR %d inflateInit (%s)",
zerr, decode_zlib_err(zerr));
return -1;
}
}
while(totalBytesIn < inLen ) {
int compChunkSize = ((inLen - totalBytesIn) > 5120) ? 5120 :
(inLen - totalBytesIn);
memcpy(in, inBuf + totalBytesIn, compChunkSize);
zstrm.avail_in = inLen - totalBytesIn;
zstrm.next_in = in ;
zstrm.avail_out = CHUNK_SZ;
zstrm.next_out = out;
inflatedBytes = 0;
while(ret != Z_STREAM_END) {
ret = inflate(&zstrm, Z_NO_FLUSH);
if(ret < 0) {
uerror(" Error %d inflate (%s)", ret, decode_zlib_err(ret));
(void)inflateEnd(&zstrm);
return ret;
}
inflatedBytes = CHUNK_SZ - zstrm.avail_out;
if(inflatedBytes == 0) {
unotice("\n Unable to decompress data - truncated");
break;
}
totalBytesIn += zstrm.total_in;
decompByteCounter += inflatedBytes;
memcpy(dstBuf + savedByteCntr, out, inflatedBytes);
savedByteCntr = decompByteCounter;
}
// Reset inflater for additional input
ret = inflateReset(&zstrm);
if(ret == Z_STREAM_ERROR){
uerror(" Error %d inflateReset (%s)", ret, decode_zlib_err(ret));
(void)inflateEnd(&zstrm);
return ret;
}
}
if(isLastBlk){
ret = inflateEnd(&zstrm);
if(ret < 0) {
uerror("Fail inflateEnd %d [%s] ", ret, decode_zlib_err(ret));
return (ret);
}
}
*outLen = decompByteCounter;
return 0;
}
提前感谢您的支持。
谢谢, 沙迪亚。
答案 0 :(得分:1)
您在使用inflateData()
例程时出错。
首先,以这种方式使用静态变量是一个可怕的想法。如果您使用inflateData()
两次调用isFirstBlk
而没有isLastBlk
为zstrm
的中间调用,那么您将清除对第一组分配的引用,从而导致内存泄漏。< / p>
要避免此类错误,您应该跟踪isFirstBlk
是否已初始化,并拒绝任何初始化已初始化的流的尝试。更好的是,甚至没有zstrm
,只需在第一次通话时以及在isLastBlk
为isFirstBlk
的电话后立即进行的任何通话中初始化isLastBlk
。
因此,您要么执行上述操作,请使用function Duck() {}
Duck.prototype.quack = function() {alert('Quaaaaaack!');};
Duck.prototype.feathers = function() {alert('The duck has white and gray feathers.');};
//Duck.prototype.name = function() {alert('Donald Duck');};
function Person() {}
Person.prototype.quack = function() {alert('The person imitates a duck.');};
Person.prototype.feathers = function() {alert('The person takes a feather from the ground and shows it.');};
Person.prototype.name = function() {alert('Rick James');};
function inTheForest(object) {
object.quack();
object.feathers();
object.name();
}
function game() {
var donald = new Duck();
var john = new Person();
inTheForest(donald);
inTheForest(john);
}
game();
true调用两次,否则无法使用 var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
调用true。