问题标签 [object-pooling]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
40 浏览

c++ - 并发对象池,其产品的生命周期完全由包含对象的智能指针控制

我想在 C++ 中设计一个并发对象池,可能的原型为:

  • 一旦对象(产品)被返回,它的生命周期就完全由包含该对象的智能指针控制。
  • 池可能被多个线程使用。

我们如何在用户完成后自动回收对象/内存?

我的想法是在池中有一个 delete() 方法,该方法在产品的析构函数中调用。

有更好的设计吗?例如,产品类与池耦合较少的一种方式(注意它是一个通用池)。欢迎任何想法。

0 投票
2 回答
254 浏览

design-patterns - 对象池模式——关注点分离——封装:谁负责删除一个实例?

情况

在开发过程中,我实现了称为对象池模式的设计模式。基本上这意味着我们的类有一个静态的公共方法和一个静态保护的属性。该属性携带所有实例,如果提供了某个对象键,则可以通过静态公共方法检索这些实例。我使用一个调用方法get_instance将实例检索到本地引用变量中,然后在其上调用其他方法。在我们的例子中,一个包装函数模块调用get_instance,然后在该实例上调用一些方法。在特定情况下,某个实例的生命周期结束。因此,它必须从对象池中删除。到目前为止,我在实例方法中执行此操作,其中对象从池(表)中删除自身。

假设

功能模块中的外部引用应该已经失效,因为它确实引用了一个不存在的对象。如果我假设正确,垃圾收集器现在应该携带这个孤立的引用。(通常情况相反:一个未引用的对象通常被 GC 杀死。)在这种情况下,我仍然假设我的功能模块中的本地引用也应该被收集。因为它所引用的对象已从对象池中删除。尽管如此,直到现在,我仍然调用Free lr_myreference. 一位同事说,最好实现一个静态公共方法,它不会对引用起作用,而只是在调用Free lr_myreference.

问题

一般来说,我在想:谁负责从池中删除对象?引用表中条目的其他本地引用(“原始引用”)呢?

0 投票
1 回答
601 浏览

c# - 3D无限跑者游戏平台生成给出异常

情况:我指的是我的项目的教程,代码中有一个对象池的概念。

问题:发生的情况是,在我编写生成平台(PlatformManager.cs)的脚本后,我得到一个异常说,

InvalidOperationException:由于对象 System.Collections.Generic.Queue`1[UnityEngine.Transform].Peek () PlatformManager.Update () (在 Assets/Platform/PlatformManager.cs:35)的当前状态,操作无效

PlatformManager.cs 脚本:

提前致谢。

0 投票
2 回答
1497 浏览

c# - 将类的所有字段设置为默认值的最有效方法

我正在尝试创建一个对象池框架。每次客户端请求某种类型的对象时,我都会从缓存(队列)中返回一个对象,或者如果缓存中没有对象,则创建一个新对象。

现在,当客户端代码处理完对象后,将其传递给框架以再次缓存。但是要使这种模式起作用,需要将对象重置为初始状态。每个字段都必须设置为其default(T). 为每个班级手动执行此操作将是容易出错且乏味的工作。

当然,性能是首要考虑的问题。我正在寻找最有效的解决方案。

编辑:

至于动机,这是一个unity3d游戏项目,垃圾收集是unity中的一个大问题。您从垃圾收集中保存的每个字节都很重要。因此,与创建新对象的最快、最简单、更合理的方式相比,缓存对象是可取的。

0 投票
3 回答
2634 浏览

java - Java - ThreadLocal 还是并发对象池?

哪种方法更适合访问非线程安全对象

使用ThreadLocal对象:

使用并发对象池

或您想提供的其他方法?

重要因素是:

  • 表现
  • 内存使用情况
  • 垃圾收集

一般来说,每种方法的优缺点什么

它们之间有什么明显的区别吗?

谢谢。

编辑

Kryo使用的并发对象池的示例。

0 投票
1 回答
49 浏览

c# - 将 GameObject 添加到类中的列表时出错

我在将 a 添加GameObject到 a时遇到问题List<>。当我构建这个程序时,会发生错误poolInstances.Add(clone)

错误:List.Add(RecyclingGameObject) 有一些无效参数。

线上也出现错误return clone;

错误:无法将 Gameobject 隐式转换为 RecyclingGameObject

这是我的代码:

0 投票
1 回答
101 浏览

collision-detection - 当障碍物与边界碰撞时,如何编写障碍物回到我的对象池中?

请不要被我冗长的问题吓倒,我相信我只是措辞奇怪,哈哈。我遵循了 Mike Geig 的关于在 Unity 中使用对象池的优秀教程,我很好地理解了这个概念。我只是有一个问题,这个问题让我头疼了将近一周。当它与南墙(标记为“南墙”)碰撞时,如何让这个障碍物回到我的对象池中?我有一张图片和我的脚本:替代文字

(下面的脚本是我的通用池程序脚本,我从对象池教程中更改了一点点)

(下面的脚本是产生障碍的原因,我从 Space Shooter 教程中得到它并对其进行了一些修改!)

(下面的脚本是移动障碍的原因)

0 投票
1 回答
264 浏览

destroy - 如何正确使用 IEnumerator 对象池敌人波

希望有人可以帮助我解决这个问题。我正在尝试将 IEnumerator 与我的对象池脚本结合起来,以实例化波中的敌人。但是我不能让它们实例化而不立即摧毁自己 2 或 3 次,然后实例化一波敌人并且不再产生。谁能帮我看看我哪里出错了?

0 投票
3 回答
3428 浏览

c# - Unity:需要在返回池时重置池对象。也许使用 ScriptableObject?

我最近一直在尝试统一对象池,以同时加快多个游戏对象的实例化。

然而,由于这些是相当复杂的对象,当它们回到池中时,我需要重置它们。

我读到使用 ScriptableObject 可能是存储默认值以便轻松重置的好方法。但为了做到这一点,我需要在运行时加载一个新的 ScriptableObject 来存储对象的实际值。

所以在伪代码中,我会有一个带有public MyScriptableData dataand的类public MyScriptableData defaults

1) 使用默认的 ScriptableObject 创建新的池化对象data = defaults;

2) 做一些在对象生命周期内改变脚本对象值的事情

3) 停用,然后将池化对象返回到池中,将 scriptableObject 重置为其默认值(data = defaults;再次)。

我有3个主要问题:

A)我不确定如何实际实现这一点。在我看来,在第 2 步中,默认值将被更改。因此,重置为默认值将无济于事。我想过使用创建我的可编写脚本对象的新实例

data = ScriptableObject.CreateInstance<MyScriptableData>();

但是我将如何从 复制默认值defaults,以确保永远不会更改默认值?我希望默认值可以在统一编辑器中作为资产进行编辑。

B) 如果我使用 CreateInstance,性能会很差吗?我做这个对象池的全部原因是为了降低对象实例化的性能成本。我不想通过实例化可编写脚本的对象来重新引入慢代码。

C) 这种方法好吗?还是有更好的方法在返回池之前重置对象?

根据一些答案进行编辑:我已经有一个包含一长串字段的设置,然后将这些字段的默认值存储在字典中。但是我发现每次我想添加/更改/删除一个字段时,我都必须在几个地方更改代码

尝试的解决方案(但错误,见下文):我为 ScriptableObject 创建了一个扩展方法:

最终解决方案:

上面的脚本用于克隆可编写脚本的对象,但是,我似乎在使用该解决方案时走错了路。

下面的几个人指出,对于大多数应用程序来说,池化在统一中并不那么重要。我最初尝试使用池化,因为根据分析器,我的帧速率约为 30-15 fps,我认为池化将有助于改善这一点。

根据评论我挖得更深一点,发现有一个名为 LogStringToConsole 的过程。我对自己说,这能像我的 Debug.Log 语句那样简单吗?我删除了它们,巨大的尖峰消失了。显然 Debug.Log 会导致巨大的性能问题。现在我的帧速已经超过 60fps。正因为如此,我决定不合并这些对象(但在另一种场景中,我仍然在更简单的对象上使用池,这些对象每秒会产生几次)。这意味着我根本不需要担心这里的可编写脚本的对象。我现在拥有并实例化加载一个预制件和一个 Init 方法来进行设置,并且对象在用完时被销毁。

当我重新使用实例化/销毁时,我没有注意到性能有显着变化。感谢所有的回复!

0 投票
3 回答
3198 浏览

c# - 通用对象池

是否可以创建一个在其中创建新对象的通用对象池?另外,如果这个对象创建可以接收参数,那就太好了。

如果它可以接收参数,它可以像这样使用。

或者,如果无法提供参数,这也可以。