JavaScript内存堆大小在从页面到页面导航时不断增加。如何识别内存泄漏?
我正在使用MongoDB数据库和Mongoose驱动程序运行React + Next.js电子商务网站。当使用Chrome浏览器内存探测器时,刚启动应用程序时的初始内存堆大小约为30 MB。
如果我与仅坐在一页的网站进行交互,则内存堆的增加不会增加。但是,例如,当导航到其他页面时,转到所有产品页面,向下滚动并加载更多的无限滚动产品,内存堆的大小会迅速增加。在下面的屏幕截图中,可以看出快照3& 4,在导航到其他页面,加载产品并查看它们时,堆尺寸增加了30 MB。
我在本地计算机上正在生产模式上运行这些测试。在我的网站现场部署的VP中,运行我网站的节点流程消耗的RAM数量似乎也随着时间而增加。这是我顶级命令结果的屏幕截图。 PID 1159的第二个过程是运行网站的过程。当前,%MEM列显示它使用的是4.9%的内存,但是在一天中,它的使用时间超过7%,直到我重新启动应用程序并降低了内存使用情况。
我猜想有一个内存泄漏,但无法弄清楚是什么原因引起的。
我怀疑的某些事情是不寻常的:
- 当导航到所有产品页面并无限滚动以加载更多产品时,那就是记忆堆急剧增加的时候。从该页面浏览后,似乎有很多独立的HTML元素似乎没有收集垃圾。这是内存剖面的屏幕截图。
- 在系统 / jsarraybufferdata树内的堆快照摘要中,在窗口中有一个名为Mongoose的对象,在保留尺寸列中显示高百分比。为什么将猫鼬加载到窗口中?
所有这些都是令人担忧的,因为我的VPS的性能差,我怀疑高度记忆使用情况是原因。
用于调试目的的一些额外信息:
我正在使用以下中间件建立与MongoDB数据库的连接:
const mongoose = require('mongoose')
const connectDB = handler => async (req, res) => {
if (mongoose.connections[0].readyState) {
return handler(req, res);
}
await mongoose.connect(`MONGODB_URI`, {
useUnifiedTopology: true,
useNewUrlParser: true
});
return handler(req,res);
};
export default connectDB
我正在以下面的方式导出Mongoose模式:
import mongoose from 'mongoose';
const productSchema = mongoose.Schema({
section: String,
category: String,
category_slug: String,
sub_category: String,
sub_category_slug: String,
product_code: String,
title: String,
description: String,
batch_number: String,
tags: [],
warranty: String,
similar_products: [{label: String, value: String, _id: false}],
compatibility: {
make_and_model: [],
year: [],
engine_chasis: []
},
product_variants: [{ type: new mongoose.Schema(
{
variant_code: String,
variant_title: String,
slug: String,
color_variant: Boolean,
images: [{id: Number, name: String}],
status: String,
views: Number,
variant_details: [{ type: new mongoose.Schema(
{
size: String,
local_price: { type: Number, default: 0 },
local_discount: { type: Number, default: 0 },
inventory: [{
type: new mongoose.Schema(
{
branch_id: mongoose.Schema.Types.ObjectId, quantity: Number
}
)
}]
}
)
}]
}
)
}]
}, {timestamps: true})
mongoose.models = {};
export default mongoose.models.Product || mongoose.model("Product", productSchema);
如果需要,我愿意提供更多信息以进行调试目的。任何解决方案和反馈都非常感谢。
I am running a React + Next.js e-commerce website with MongoDB database and mongoose driver. When using the Chrome browser memory profiler, the initial memory heap size when the app is just started is around 30 MB.
If I interact with the website sitting in only one page, the memory heap doesn't increase much. However, when navigating to other pages, for example, moving to the all products page and scrolling down and loading more products with infinite scrolling, the memory heap size increases rapidly. In the screenshot below, it can be seen that between the comparison of snapshot 3 & 4, the heap size increased by 30 MB when navigating to other pages, loading products and viewing them.
I am running these tests on production mode in my local computer. In my VPS where the website is deployed live, the amount of RAM consumed by the node process running my website also seems to increase over time. Here is a screenshot of my top command results. The second process with PID 1159 is the one that's running the website. Currently the %MEM column shows it is using 4.9% of the memory but over the day it goes over 7% until I restart the app and the memory usage comes down.
I am guessing there's a memory leak but not being able to figure out what's causing it.
Some things that I doubt are unusual:
- When navigating to all products page and infinitely scrolling to load more products, that is when the memory heap increases dramatically. After navigating away from that page, there seems to be a lot of detached HTML elements that doesn't seem to be garbage collected. Here is a screenshot of the memory profiler.
- In the heap snapshot summary inside the system / JSArrayBufferData tree, there is an object named mongoose in Window that shows a high percentage in the Retained Size Column. Why is mongoose loaded into Window?
All these are concerning because my VPS has been performing poorly and I suspect high memory usage is the cause.
Some extra information for purpose of debugging:
I am establishing connection to the mongodb database using the following middleware:
const mongoose = require('mongoose')
const connectDB = handler => async (req, res) => {
if (mongoose.connections[0].readyState) {
return handler(req, res);
}
await mongoose.connect(`MONGODB_URI`, {
useUnifiedTopology: true,
useNewUrlParser: true
});
return handler(req,res);
};
export default connectDB
I am exporting mongoose Schemas in the following way:
import mongoose from 'mongoose';
const productSchema = mongoose.Schema({
section: String,
category: String,
category_slug: String,
sub_category: String,
sub_category_slug: String,
product_code: String,
title: String,
description: String,
batch_number: String,
tags: [],
warranty: String,
similar_products: [{label: String, value: String, _id: false}],
compatibility: {
make_and_model: [],
year: [],
engine_chasis: []
},
product_variants: [{ type: new mongoose.Schema(
{
variant_code: String,
variant_title: String,
slug: String,
color_variant: Boolean,
images: [{id: Number, name: String}],
status: String,
views: Number,
variant_details: [{ type: new mongoose.Schema(
{
size: String,
local_price: { type: Number, default: 0 },
local_discount: { type: Number, default: 0 },
inventory: [{
type: new mongoose.Schema(
{
branch_id: mongoose.Schema.Types.ObjectId, quantity: Number
}
)
}]
}
)
}]
}
)
}]
}, {timestamps: true})
mongoose.models = {};
export default mongoose.models.Product || mongoose.model("Product", productSchema);
I am willing to provide more information if needed for debugging purpose. Any solutions and feedback are highly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论