TypeScript class 中的内存泄漏与间隔和猫鼬获取
Memory leak in TypeScript class with interval and mongoose fetching
我用 TypeScript 做了这个 class。它有一个 websocket,它会发出数据,这些数据是基于一些参数用 mongoose 预取的。
请注意:这是演示代码,不是真实代码。我复制它是为了尽可能容易理解
import { Server as SocketServer } from 'socket.io';
import { Animal, AnimalModel } from './animal.model.ts';
// ^^^^^^^ this is just a basic properties interface and a mongoose schema
export class Stream {
private io: SocketServer;
private breed: string;
private animals: Array<Animal>;
constructor(
io: SocketServer,
breed: string
) {
this.io = io;
this.breed = breed;
this.fetch(); // initial fetch
setInterval(() => this.emit(), 1000); // emit every second
setInterval(() => this.fetch(), 1000); // fetch it every second for updates
// ^^^ once I comment this line out, it doesn't seem to leak memory anymore
}
/**
* Fetch the animals list based on the set breed
*/
private async fetch(): Promise<void> {
this.animals = await AnimalModel.find({breed: this.breed}).limit(20).exec(); // one fetch is about 100kb
}
/**
* Emit the animals list to people who are subscribed to the breed
*/
private emit(): void {
this.io.in(this.breed).emit("animals", JSON.stringify(this.animals))
}
}
我这样生成这些动物:
import { AnimalModel } from './animal.model.ts';
const socket = makeSocket(); // some function to make new socket.io instance
const initialize = async () => {
// About 25 animals
const animalsList = await AnimalModel.find().exec();
animalsList.forEach(animal => {
new Stream(socket, animal.breed); // generates a new stream for every animal breed with a reference to the socket
});
};
initialize();
现在的问题是一次获取动物(每个品种)大约 100kb,将其乘以 25,即每秒向内存堆添加大约 2.5 MB。每当我评论取出时,它都不会进一步增加。在我看来,获取功能似乎没有被释放。
我已经尝试了几个小时,但我无法让它工作,比如使用 Chrome NodeJS 调试工具,编写不同的函数 - 但没有结果..任何人都可以帮助我解决这个问题或想出不泄露的代码?
PS:我有一些堆快照以备不时之需
我发现了问题所在。
对数据库的一个查询大约需要 0.2 秒,其中 102 个数据流大约需要 19 秒。
在流中,它每秒查询一次,因此这些请求越来越多。
我通过将间隔更改为预期的网络请求时间来修复它。
我用 TypeScript 做了这个 class。它有一个 websocket,它会发出数据,这些数据是基于一些参数用 mongoose 预取的。
请注意:这是演示代码,不是真实代码。我复制它是为了尽可能容易理解
import { Server as SocketServer } from 'socket.io';
import { Animal, AnimalModel } from './animal.model.ts';
// ^^^^^^^ this is just a basic properties interface and a mongoose schema
export class Stream {
private io: SocketServer;
private breed: string;
private animals: Array<Animal>;
constructor(
io: SocketServer,
breed: string
) {
this.io = io;
this.breed = breed;
this.fetch(); // initial fetch
setInterval(() => this.emit(), 1000); // emit every second
setInterval(() => this.fetch(), 1000); // fetch it every second for updates
// ^^^ once I comment this line out, it doesn't seem to leak memory anymore
}
/**
* Fetch the animals list based on the set breed
*/
private async fetch(): Promise<void> {
this.animals = await AnimalModel.find({breed: this.breed}).limit(20).exec(); // one fetch is about 100kb
}
/**
* Emit the animals list to people who are subscribed to the breed
*/
private emit(): void {
this.io.in(this.breed).emit("animals", JSON.stringify(this.animals))
}
}
我这样生成这些动物:
import { AnimalModel } from './animal.model.ts';
const socket = makeSocket(); // some function to make new socket.io instance
const initialize = async () => {
// About 25 animals
const animalsList = await AnimalModel.find().exec();
animalsList.forEach(animal => {
new Stream(socket, animal.breed); // generates a new stream for every animal breed with a reference to the socket
});
};
initialize();
现在的问题是一次获取动物(每个品种)大约 100kb,将其乘以 25,即每秒向内存堆添加大约 2.5 MB。每当我评论取出时,它都不会进一步增加。在我看来,获取功能似乎没有被释放。
我已经尝试了几个小时,但我无法让它工作,比如使用 Chrome NodeJS 调试工具,编写不同的函数 - 但没有结果..任何人都可以帮助我解决这个问题或想出不泄露的代码?
PS:我有一些堆快照以备不时之需
我发现了问题所在。
对数据库的一个查询大约需要 0.2 秒,其中 102 个数据流大约需要 19 秒。
在流中,它每秒查询一次,因此这些请求越来越多。
我通过将间隔更改为预期的网络请求时间来修复它。