Cause NuxTJS framework was used for development in the company’s project, and no abnormality occurred in the development and testing process. After about five or six days of live production, Node became abnormal and pM2 could not recover itself. You need to enter the production environment to restart the project. The logs show that the production server slowly piles UP TCP links. Finally raise the Node program CPU 100%. In the initial stage, it was thought that nginx reverse proxy node service, but files under _nuxt are not proxy are read through Node. After reconfiguring the static file read rules, the problem persists. I read somewhere that a Node memory leak can cause a Node process to run out of CPU.
The use of tools
- node-heapdump
- Chrome Debugger
Installation node – heapdumps. And the code is configured in nuxt.config.js.
Var headpdump = require('heapdump') setInterval(function () {console.log('st headpdump') headpdump.writeSnapshot(function(err, filename) { console.log('dump written to', filename) }) }, 15000) module.exports = {... // nuxt configuration}Copy the code
I set 1.5 seconds to take a memory snapshot. And take a snapshot according to the following rules.
- Load the page and wait for a snapshot
- Refresh the page once and wait for a snapshot // 3. Refresh the page several times and wait for a snapshot // 4. Wait a while to take a snapshot.
Chrome,memory view explanation
Column field explanation: ● Constructor — Class name Distance — Estimate the referential level Distance from the object to the root ● Object Count — give how many Objects of this class are currently Shallow Size — Retained Size — Total memory Retained by a Retained object (excluding the memory of other internally referenced objects) (unit: bytes) ● Retained Size — Total memory Retained by a Retained object (unit: bytes). One version of the program code is already unknown. One version of the program code is closure – Array – Unknown. One version of the JS Object type is System – Unknown. Sometimes when a new property is added to the object, the name of the property will also appear here
Open chrome Developer Tools and switch to memory. load the hepdump generated file in the root directory.
Load the first page snapshot separately, followed by the snapshot after the refresh.
Switch the view to ComparisonYou can see that after a refresh, there are 69 more closures left unreleased. Open the closure method to see a large number of unreleased requests. Examine the request method code in the Services.
import Urls from './url'
import Fetch from './fetch.js'
let fn = {}
Object.keys(Urls).forEach(key => {
fn[key] = (data, headers) => {
return new Promise((resolve, reject) => {
resolve(Fetch(Urls[key].url, {method: Urls[key].method, data, headers}))
})
}
})
export default fn
Copy the code
If a new Promise is returned but the data used is passed to the next layer through the arrow method, the closure will not be fully released. Because incoming data always has references that cannot be gc. The modified code is as follows:
import Urls from './url'
import Fetch from './fetch.js'
let fn = {}
Object.keys(Urls).forEach(key => {
fn[key] = function (data, headers) {
return Fetch(Urls[key].url, {method: Urls[key].method, data, headers})
}
})
export default fn
Copy the code
A second look at the memory snapshot shows that all closures have been reclaimed. The memory leak problem is basically over.
Refer to article sources frontenddev.org/link/js-mem…