具有回调函数和节点计划的 Node.js 内存使用情况

Node.js memory usage with callback functions and node-schedules

提问人:user13020816 提问时间:5/6/2023 更新时间:5/6/2023 访问量:79

问:

因此,我创建了一些代码,当(扩展)被传递到时,将在 和 之间的随机持续时间(以秒为单位)被添加到当前日期上,并将在当前日期等于随机日期时调用。eventnode-schedulethis.scheduler.schedule()minmaxhandler

    start(lock){
        const event = new RandomScheduledEvent({
            extension: this.extension.slug, 
            lock: lock.lock.id, 
            slug: "random-event",
            min: 2,
            max: 2,
            handler: () => { this.eventCycle(lock) }
        });

        this.scheduler.schedule(event)
    }

    /**
     * 
     * @param {RandomEventLock} oldLock 
     */
    async eventCycle(oldLock){
        const updatedLock = await this.getLock(oldLock.lock.id, oldLock.tokenManager);
        if(updatedLock.isTrusted() == true){
            this.scheduler.deschedule(this.scheduler.findOne({lock: oldLock.lock.id, slug: "random-event"}))
            console.log(this.scheduler);
        }
        return;
    }

我担心的是这些随机事件会占用多少内存,我不确定 JavaScript 如何处理这些类型的调用。我估计在任何给定时刻都会发生大约 100 个这样的计划,并且我托管的服务器对内存消耗非常严格。 (的参数)存储了一个相当大的对象,我不知道这个对象是否会在内存中保留,直到出现新的计划。理想情况下,该对象将仅用于最新信息,并在完成后将其丢弃,实际上只存储oldLockeventCyclegeteventCyclenode-schedule

this.getLock()正在从 API 中检索信息,并将该数据附加到存储我数据的对象中,用于处理我需要的任何操作,例如事件发生的频率、是否启用了锁等。

JavaScript .js 回调 节点调度

评论


答:

2赞 jfriend00 5/6/2023 #1

如果你问的是将在内存中保留多长时间,那么这个答案取决于垃圾回收器的工作方式。只要任何代码仍然可以访问/使用,它就不能被垃圾回收,并且会存在于内存中。oldLockoldLock

在特定代码中,将要传递给方法的对象传递给方法,而该对象又在处理程序回调中使用该值。因此,至少,它会保留在内存中,直到被调用或直到无法再调用。如果在 RandomScheduledEvent 触发时调用该函数,则它肯定会保留在内存中,直到该事件触发并调用该函数。oldLockstart()handler()handler()handler()

然后,在方法中,对象被多次引用,因此它在该方法执行的生存期内仍然可用,包括当它处于调用状态时,因为在此之后被引用。eventCycle()oldLockawait this.getLock()oldLock

虽然垃圾回收器在多长时间内清理对象的细节没有按规范详细说明,但可以在您的代码中更快地使垃圾回收符合条件,这样就可以在 API 调用期间进行 GCed,并且不必在 API 调用完成之前徘徊。您可以通过在更改为以下内容后不引用来做到这一点:oldLockawait this.getLock()oldLockawait

async eventCycle(oldLock){
    const id = oldLock.lock.id;
    const updatedLock = await this.getLock(id, oldLock.tokenManager);
    if(updatedLock.isTrusted() == true){
        this.scheduler.deschedule(this.scheduler.findOne({lock: id, slug: "random-event"}))
        console.log(this.scheduler);
    }
    return;
}

这是否会产生实际影响完全取决于垃圾回收器的内部结构(未指定,可以更改),但它可以使其更快地符合 GC 的条件,因此肯定不会受到伤害。

你可以让它更有可能更快地获得 GCed,甚至不把它传递给 .相反,只需传递您实际需要的两个属性:eventCycle()

async eventCycle(id, tokenManager){
    const updatedLock = await this.getLock(id, tokenManager);
    if(updatedLock.isTrusted() == true){
        this.scheduler.deschedule(this.scheduler.findOne({lock: id, slug: "random-event"}))
        console.log(this.scheduler);
    }
    return;
}

P.S. 在另一个话题上,你似乎很容易受到未经处理的拒绝。如果拒绝,则没有处理程序。this.getLock()