我正在处理流式套接字上的大量数据.使用数据并留给GC进行清理.我想预先分配一个可重用的池并重复使用它来防止大量的GC.
谁能帮我?
我有一个通用类GenericClass<T>
,我想池化实例。
我有兴趣看看是否可以获得语法:
MyGenericPool = new GenericPool<GenericClass>();
// Or maybe it's MyGenericPool = new GenericPool<GenericClass<>>();
GenericClass<TGenericParam> GenericClassInstance =
MyGenericPool.Get<TGenericParam>();
Run Code Online (Sandbox Code Playgroud)
(我对泛型的理解是,不,我不能,别傻了,语法不存在/不起作用,但我对其他人的想法很感兴趣)。
我有点怀疑,因为从我对类型的理解来看,从类型系统的角度来看,它们并没有真正相关GenericClass<string>
。GenericClass<int>
现在,我意识到我可以接近,即:
GenericClass<TGenericParam> GenericClassInstance =
GenericPool.Get<GenericClass<TGenericParam>>();
Run Code Online (Sandbox Code Playgroud)
然后把它GenericPool
存储在Dictionary<Type, ObjectPool<object>>
某个地方。
我有兴趣看看是否可以避免这样做。我不想每次作为调用者只更改泛型类型参数时都必须指定泛型类型。我还希望能够强制(编译时)所有进入我的对象GenericObjectPool<T>
都是一组通用类型(T<>
)。
我认为问题源于无法将泛型类型参数视为泛型本身。如果我能做到这一点(我已经可以了吗?)那么也许像下面这样的东西可能会起作用:
public class GenericClassPool<TGeneric> where TGeneric : class<>
{
private readonly Dictionary<Type, object> objectPools = new Dictionary<Type, object>();
private void EnsureObjectPoolExists<TGenericParam>()
{
if (!objectPools.ContainsKey(typeof(TGenericParam)))
{
objectPools.Add(typeof(TGenericParam), new ObjectPool<TGeneric<TGenericParam>>(() => Activator.CreateInstance(typeof(TGeneric<TGenericParam>)) as TGeneric<TGenericParam>));
}
}
private ObjectPool<TGeneric<TGenericParam>> …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个守护进程来获取某些游戏的服务器统计信息。
在编译中我收到一条消息:
无法访问 org.apache.commons.pool2.impl.GenericObjectPoolConfig 类文件,找不到 org.apache.commons.pool2.impl.GenericObjectPoolConfig
在这行代码中:
是否可以创建shared_ptr的对象池?在我的脑海中勾勒出这一点,我可以看到两种方法可以做到这一点,但每种方法都有一个缺陷:
如果 T 对象存储在可重用池中,则在 get() 请求上将 T 包装在 Shared_ptr 中的行为将导致每次在堆上重新分配控制块 - 因此打破了对象池的概念。
如果shared_ptr对象存储在可重用池中,则shared_ptr对象必须停止存在才能启动自定义删除器,并且只能使用T指针调用自定义删除器函数。所以没有什么可以回收的。
我最近一直在尝试统一对象池,以便一次加速几个游戏对象的实例化.
但是,由于这些是相当复杂的对象,我需要在它们返回池中时重置它们.
我读到使用ScriptableObject可能是存储默认值以便轻松重置的好方法.但为了做到这一点,我需要在运行时加载一个新的ScriptableObject来存储对象的实际值.
所以在伪代码中,我有一个带public MyScriptableData data
和的类public MyScriptableData defaults
1)使用默认的ScriptableObject创建新的池化对象data = defaults;
;
2)做一些在对象生命周期内改变脚本对象值的东西
3)取消激活,然后将池化对象返回池,将scriptableObject重置为默认值(data = defaults;
再次).
我有3个主要问题:
A)我不确定如何实际实现这一点.在我看来,在步骤2中,默认值将被更改.因此,重置为默认值将不起作用.我考虑过使用创建脚本对象的新实例
data = ScriptableObject.CreateInstance<MyScriptableData>();
但是,我将如何复制默认值defaults
,确保永远不会更改默认值?我希望默认值可以在Unity编辑器中作为资产进行编辑.
B)如果我使用CreateInstance,性能会不好?我正在做这个对象池的全部原因是为了降低对象实例化的性能成本.我不想通过实例化脚本化对象来重新引入慢速代码.
C)这种方法好吗?或者是否有更好的方法在返回池之前重置对象?
编辑基于一些答案:我已经有一个具有很长字段列表的设置,然后将这些字段的默认值存储在字典中.但我发现每次我想添加/更改/删除字段时,我都必须在几个位置更改代码
ATTEMPTED SOLUTION(但错误,见下文):我为ScriptableObject创建了一个扩展方法:
using UnityEngine;
using System.Reflection;
public static class ScriptableObjectExtension {
public static T ShallowCopy<T> (this T orig) where T : ScriptableObject {
T copiedObject = ScriptableObject.CreateInstance<T> ();
FieldInfo[] myObjectFields = orig.GetType ().GetFields (
BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Instance);
foreach (FieldInfo fi in myObjectFields) {
fi.SetValue (copiedObject, …
Run Code Online (Sandbox Code Playgroud) 在Objective-C中有一个很好的方法可以做到这一点,还是我必须编写自己的乏味逻辑?
我在iPhone游戏中每帧创建并销毁一些小状态对象.如果我可以只重用池中的对象,那将是很好的.
我有一个 couchdb 数据库,并且正在并行查询它。现在,我想创建一个连接池,因为我发现了设计中的瓶颈 - 我使用的是 couchd 的单个实例,因此并行化因此失败。
我在网上搜索了连接池实现,但我无法找到适合 couchdb 的正确 java 连接池实现 - 大多数框架都支持关系数据库。如果有人能帮助我,我将不胜感激。
是否可以创建一个在其中创建新对象的通用对象池?此外,如果此对象创建可以接收参数,那将是很好的.
public interface IPoolable
{
void Dispose();
}
public class ObjectPool<T> where T : IPoolable
{
private List<T> pool;
public T Get()
{
if(pool.count > 0)
{
return pool.Pop();
}
else
{
return new T(); // <- How to do this properly?
}
}
}
public class SomeClass : IPoolable
{
int id;
public SomeClass(int id)
{
this.id = id;
}
public void Dispose()
{
}
}
public class OtherClass : IPoolable
{
string name;
int id;
public OtherClass(string name, …
Run Code Online (Sandbox Code Playgroud)