Node.js使用回调函数和节点调度的内存使用

vcirk6k6  于 2023-05-06  发布在  Node.js
关注(0)|答案(1)|浏览(159)

因此,我创建了一些代码,当event(扩展的node-schedule)传入this.scheduler.schedule()时,minmax之间的随机持续时间(以秒为单位)将被添加到当前日期,当当前日期等于随机日期时,将调用handler

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个这样的时间表发生在任何给定的时刻和服务器即时通讯主机上是非常严格的内存消耗。oldLockeventCycle的参数)存储了一个相当大的对象,我不知道这个对象是否会在内存中持久存在,直到新的调度发生。理想情况下,该对象将仅用于get最新信息,并在eventCycle完成后丢弃,实际上只存储node-schedule
this.getLock()正在从API中检索信息,并将该数据附加到存储我的数据的对象中,用于处理我需要的任何操作,例如事件发生的频率、锁是否被启用等。

lf3rwulv

lf3rwulv1#

如果您问的是oldLock将在内存中停留多长时间,那么答案取决于垃圾收集器的工作方式。只要任何代码仍然可以访问/使用oldLock,它就不能被垃圾收集,并将存在于内存中。
在您的特定代码中,您将成为oldLock的对象传递给start()方法,然后在处理程序回调中使用该值。因此,至少,它会一直留在内存中,直到handler()被调用,或者直到handler()不能再被调用。如果在RandomScheduledEvent触发时调用它,那么它肯定会留在内存中,直到该事件触发并调用handler()函数。
然后,在eventCycle()方法中,oldLock对象被多次引用,因此它在该方法执行的生命周期内仍然可用,包括在await this.getLock()调用时,因为oldLock在此之后被引用。
虽然规范中没有详细说明垃圾收集器清理对象的确切时间,但可以在代码中使oldLock更快地符合垃圾收集条件,以便在await this.getLock()期间进行GCed,并且不必在API调用完成之前挂起。您可以通过更改为以下内容,在await之后不引用oldLock

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的要求,因此肯定不会有什么坏处。
你甚至可以不把它传递给eventCycle(),这样更有可能更快地获得GCed。相反,只需传递您实际需要的两个属性:

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()拒绝,则没有处理程序。

相关问题