【发布时间】:2020-12-19 00:54:32
【问题描述】:
嘿,我在 heroku 中托管的 nodejs 服务器上遇到了奇怪的内存泄漏。 我试图找到泄漏两天,在我一个一个删除我的功能后,我发现这个导致了问题,但我仍然不确定问题到底出在哪里。 我可以清楚地看到 heroku 指标存在内存泄漏。 有人知道为什么这个函数会产生内存泄漏。谢谢
completeTicTacToeGame: function (game, winnerIndex, reasonForFinish, userId) {
if (userId) {
User.findOne({
_id: userId
}, function (err, user) {
if (err || user == null) {
}
else {
userLivesController.removeUserHeartWithoutResponeAndSaving(user, 'ticTacToeHearts', function (user, canPlay) {
if (canPlay) {
dateFormatterController.checkIfDateIsToday(user.lastCompitedTicTacToeGame, function (isToday, isPrevious) {
var earnCredits = 0
if (winnerIndex == 0) { earnCredits = 1 }
if (winnerIndex == 1) { earnCredits = 4 }
user.credits = user.credits + earnCredits
user.lifetimeCredits = user.lifetimeCredits + earnCredits
//increase ad today counter
user.lastCompitedTicTacToeGame = (new Date()).getTime().toString()
userBadgesController.checkIfUserNeedToWinBadgeForCredits(user, function (user) {
user.save(function (err, user) {
if (err) {
errorHandlingController.generalSendErrorWithMessage(req, res, 'serverError')
}
else {
var canPlayMoreGames = user.ticTacToeHearts > 0
if (earnCredits > 0) {
notificationController.sendNotificationToUserForNewTicTacToeGame(user, earnCredits)
rankingController.updateRankings(user, earnCredits, 'ticTacToe')
}
var canWatchAdToDoubleCredits = false
if (user.gamesWithoutAd >= ConfigParams.numberOfGamesForAd() && earnCredits > 0) {
canWatchAdToDoubleCredits = true
}
var timeLeftToNextHeart = (((ConfigParams.minutesForHeart() * 60000)) + parseInt(user.lastGivenHeart)) - ((new Date()).getTime())
var haveMaxHearts = user.mathGameHearts == ConfigParams.maxHearts() && user.memoryHearts == ConfigParams.maxHearts() && user.ticTacToeHearts == ConfigParams.maxHearts()
var canWatchVideoForHeart = true && haveMaxHearts == false
if (user.lastWatchedVideoForHeart) {
var canWatchVideoForHeart = (((ConfigParams.minutesForHeartWatchedAd() * 60000)) + parseInt(user.lastWatchedVideoForHeart)) - ((new Date()).getTime()) < 0 && haveMaxHearts == false
}
module.exports.sendMessageToSocketForComlitedGame(game, user._id.toString(), user.credits, earnCredits, canPlayMoreGames, canWatchAdToDoubleCredits, reasonForFinish, user.ticTacToeHearts, ConfigParams.maxHearts, null, user.gamesWithoutAd >= ConfigParams.numberOfGamesForAd() - 1, timeLeftToNextHeart, canWatchVideoForHeart)
}
})
})
})
}
else {
var timeLeftToNextHeart = (((ConfigParams.minutesForHeart() * 60000)) + parseInt(user.lastGivenHeart)) - ((new Date()).getTime())
var haveMaxHearts = user.mathGameHearts == ConfigParams.maxHearts() && user.memoryHearts == ConfigParams.maxHearts() && user.ticTacToeHearts == ConfigParams.maxHearts()
var canWatchVideoForHeart = true && haveMaxHearts == false
if (user.lastWatchedVideoForHeart) {
var canWatchVideoForHeart = (((ConfigParams.minutesForHeartWatchedAd() * 60000)) + parseInt(user.lastWatchedVideoForHeart)) - ((new Date()).getTime()) < 0 && haveMaxHearts == false
}
module.exports.sendMessageToSocketForComlitedGame(game, user._id.toString(), user.credits, 0, false, false, reasonForFinish, user.ticTacToeHearts, ConfigParams.maxHearts, null, user.gamesWithoutAd >= ConfigParams.numberOfGamesForAd() - 1, timeLeftToNextHeart, canWatchVideoForHeart)
}
})
}
})
}
},
【问题讨论】:
-
你有什么证据让你认为你有内存泄漏?
-
我附上了一张来自 heroku 指标平台的图片。你可以看到服务器使用的内存是如何逐分钟增加的
-
垃圾收集循环发生。这种内存使用对我来说看起来很正常。
-
可以看到内存增加超过6小时这是不正常的。之后我们达到最大内存并重新启动服务器,这就是内存下降的原因。
-
你提供的这个函数有很多外部调用者,可能其中一个或几个是泄漏的结果。正如@evgenifotia 所说,替换每个调用以查看是否泄漏内存。其他解决方案是封装并尽可能多地转换为功能代码,从而尽可能减少意外泄漏。
标签: javascript node.js express memory-leaks