技巧和故障排除

预防模拟器中的内存泄漏#

当在 Python 对象中注册 C++ 回调时,Isaac Sim 模拟器中可能会发生内存泄漏。当类中的回调函数与其关联的 Python 对象保持引用时会发生这种情况。结果是,Python 的垃圾回收无法回收与这些对象相关联的内存,从而阻止了相应的 C++ 对象被销毁。随着时间的推移,这可能导致内存泄漏和资源使用量增加。

为了防止 Isaac Sim 模拟器中的内存泄漏,务必在向模拟器注册回调时使用弱引用。这可以确保在不再需要时可以对 Python 对象进行垃圾回收,从而避免内存泄漏。Python 标准库中的 weakref 模块可用于此目的。

例如,考虑一个具有需要向模拟器注册的回调函数 on_event_callback 的类。如果在传递回调时对 MyClass 对象使用强引用,则会增加 MyClass 对象的引用计数。这会防止在不再需要时对 MyClass 对象进行垃圾回收,即不会调用 __del__ 析构函数。

import omni.kit

class MyClass:

def __init__(self):

app_interface = omni.kit.app.get_app_interface()

self._handle = app_interface.get_post_update_event_stream().create_subscription_to_pop(

self.on_event_callback

)

def __del__(self):

self._handle.unsubscribe()

self._handle = None

def on_event_callback(self, event):

# do something with the message

要解决此问题,关键是在注册回调时使用弱引用。虽然这种方法会使代码变得冗长,但它确保在不再使用时可以对 MyClass 对象进行垃圾回收。以下是修改后的代码:

import omni.kit

import weakref

class MyClass:

def __init__(self):

app_interface = omni.kit.app.get_app_interface()

self._handle = app_interface.get_post_update_event_stream().create_subscription_to_pop(

lambda event, obj=weakref.proxy(self): obj.on_event_callback(event)

)

def __del__(self):

self._handle.unsubscribe()

self._handle = None

def on_event_callback(self, event):

# do something with the message

在这个修改后的代码中,当注册回调时使用弱引用 weakref.proxy(self) ,使得 MyClass 对象可以被正确地垃圾回收。

通过遵循这种模式,您可以防止内存泄漏,并保持更高效和稳定的模拟。