V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jackple
V2EX  ›  Electron

electron 储存大量数据时 rss memory 上涨且不会下降

  •  
  •   jackple · 2021-04-21 18:00:06 +08:00 · 2296 次点击
    这是一个创建于 1310 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是我 github 上提的一个 issue, 好久了, 没人理 https://github.com/electron/electron/issues/25208

    我在主进程使用 sqlite3 或者像 demo 上用 indexeddb 都避免不了这种处理大量数据引发的内存问题

    敢问大佬们有没有解决方案

    也只是很简单的一个 demo, 没什么骚操作

    const Dexie = require('dexie')
    const fs = require('fs-extra')
    const path = require('path')
    const { v4: uuid }  = require('uuid')
    
    const DB_NAME = 'haha'
    const DB_VERSION = 1
    
    class Database extends Dexie {
        testData
    
        constructor() {
            super(DB_NAME)
            this.setupSchema()
        }
    
        setupSchema() {
            this.version(DB_VERSION).stores({
                testData: 'id, xx_id, xxxx_id, user, remark, level, deleted_at, created_at, xxxxxasdasd'
            })
            this.testData = this.table('testData')
        }
    }
    
    const db = new Database()
    
    fs.readJSON(path.join(__dirname, './data.json')).then(async res => {
        for (let i = 0; i < 30; i ++) {
            res = res.map(item => ({ ...item, id: uuid() }))
    
            const t = Date.now()
            await db.testData.clear()
            await db.testData.bulkPut(res)
            await db.testData.toArray()
            console.log(`${i} exec cost: `, Date.now() - t)
            document.getElementById('done').innerText = String(i)
        }
    })
    
    第 1 条附言  ·  2021-04-21 19:38:11 +08:00

    环境: mac big sur 数据库操作前主进程实际内存: 100MB左右 数据库操作后主进程实际内存: 170MB左右

    7 条回复    2021-04-21 19:44:21 +08:00
    EPr2hh6LADQWqRVH
        1
    EPr2hh6LADQWqRVH  
       2021-04-21 18:29:00 +08:00
    你到底是主进程还是渲染进程在搞这帮数据。。

    暴露一下 global.gc(), 自己调调 gc,看问题还在不
    jackple
        2
    jackple  
    OP
       2021-04-21 19:31:13 +08:00
    @avastms demo 是渲染进程, 可以以此为基础去看这个问题, gc 我也试过了, 没起作用

    // 主进程
    ipcMain.on('gc', () => {
    console.log('gc run in main')
    global.gc()
    })

    // 渲染进程
    fs.readJSON(path.join(__dirname, './data.json')).then(async res => {
    ... // 原逻辑

    global.gc()
    ipcRenderer.send('gc')
    alert('gc run in renderer')
    })
    EPr2hh6LADQWqRVH
        3
    EPr2hh6LADQWqRVH  
       2021-04-21 19:37:29 +08:00
    那是有点怪了,拿掉 console 试下,之前 console 会造成泄露。
    EPr2hh6LADQWqRVH
        4
    EPr2hh6LADQWqRVH  
       2021-04-21 19:39:03 +08:00
    你这 gc 隔几秒钟再执行,在你数据作用域消灭之后再触发
    jackple
        5
    jackple  
    OP
       2021-04-21 19:39:17 +08:00
    @avastms 注销掉 for 循环内 db 相关的三行就啥事没有, 证明不是 console 的问题
    jackple
        6
    jackple  
    OP
       2021-04-21 19:43:50 +08:00
    setTimeout(() => {
    global.gc()
    ipcRenderer.send('gc')
    alert('gc run in renderer')
    }, 10000)

    没有效果

    跟执行的时间点应该没有太多关系, 因为本身就是异步任务, 如果奏效, for 循环内早期的堆积的也会有部分清除才对
    jackple
        7
    jackple  
    OP
       2021-04-21 19:44:21 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3173 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 12:19 · PVG 20:19 · LAX 04:19 · JFK 07:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.