精华内容
下载资源
问答
  • 对象池

    2019-03-18 18:07:46
    这个是官方解释 Pool是对象池类,用于对象的存贮、重复使用。 对象池优化是游戏开发中非常重要的...对象池技术能很好解决以上问题,在对象移除消失的时候回收到对象池,需要新对象的时候直接从对象池中取出使用...

    这个是官方解释

    Pool 是对象池类,用于对象的存贮、重复使用。

    对象池优化是游戏开发中非常重要的优化方式,也是影响游戏性能的重要因素之一。

    在游戏中有许多对象在不停的创建与移除,比如角色攻击子弹、特效的创建与移除,NPC的被消灭与刷新等,在创建过程中非常消耗性能,特别是数量多的情况下。

    对象池技术能很好解决以上问题,在对象移除消失的时候回收到对象池,需要新对象的时候直接从对象池中取出使用。

    优点是减少了实例化对象时的开销,且能让对象反复使用,减少了新内存分配与垃圾回收器运行的机会。

    注意:对象移除时并不是立即从内存中抹去,只有认为内存不足时,才会使用垃圾回收机制清空,清空时很耗内存,很可能就会造成卡顿现象。用了对象池后将减少程序的垃圾对象,有效的提高程序的运行速度和稳定性

    合理使用对象池,可以有效减少对象创建的开销,避免频繁的垃圾回收,从而优化游戏流畅度。

    对于游戏中使用频繁的对象,例如BOSS对象,玩家模型等,在实例化的过程中,会增加开销,这时候可以采用对象池来减少内存分配与垃圾回收频率,因为回收进对象池的对象不是立即被销毁,而是储存一段时间之后,达到回收内存上限时,才会被回收。

    使用对象池回收对象时需要注意的是,在将对象回收进对象池之前先从父节点remove掉(可以调用removeSelf()),另外,不能将已经被销毁(destoryed)的sprite放回对象池

    对象池的优点是减少了实例化对象时的开销,且能让对象反复使用,减少了新内存分配与垃圾回收器运行的机会。

    展开全文
  • Netty 对象池

    万次阅读 2021-08-09 09:40:42
    Netty的对象池又是如何实现的 Netty 内存池的知识,它主要采用 jemalloc 内存分配器来实现 问题 关于 Netty 对象池,我想问你几个问题: 1 Netty 对象池与内存池的区别与联系? 2 Netty 内存池中是否使用到了对象池...

    Netty的对象池又是如何实现的

    Netty 内存池的知识,它主要采用 jemalloc 内存分配器来实现

    问题

    关于 Netty 对象池,我想问你几个问题:
    1 Netty 对象池与内存池的区别与联系?
    2 Netty 内存池中是否使用到了对象池?
    3 Netty 对象池中是否使用到了内存池?
    4 Netty 对象池实现的基本逻辑?

    展开全文
  • 对象池插件

    2018-05-29 17:27:29
    自己做的一个对象池,有很多不足的地方,但是对象池的原理已经体现了出来,适合刚开始接触对象池技术的人学习使用
  • 今天小编就为大家分享一篇对Python中小整数对象池和大整数对象池的使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 对象池 GenericObjectPool 通用对象池

    千次阅读 2019-01-28 16:44:51
    透明代理的使用 在对后端的连接中使用对象池(backend是一个池子 里面是一个域名的连接) 使用需要用到的组件 GenericObjectPool.Config DefaultChannelGroup PoolableObjectFactory BasePoolableObjectFactory ...

    透明代理的使用 在对后端的连接中使用对象池(backend是一个池子 里面是一个域名的连接)

    使用需要用到的组件
    • GenericObjectPool.Config
    • DefaultChannelGroup
    • PoolableObjectFactory BasePoolableObjectFactory
    • GenericObjectPool
    调用的流程
    • 需要重写的函数 makeObject、 validateObject、 destroyObject
    • 1、makeObject 创建对象的具体实现
    • 2、borrowObject 获取对象池中的对象简单而言就是去LinkedList中获取一个对象,如果不存在的话,要调用构造方法中第一个参数Factory工厂类的makeObject()方法去创建一个对象再获取,获取到对象后要调用validateObject方法判断该对象是否是可用的,如果是可用的才拿去使用。LinkedList容器减一
    • 3、returnObject 先调用validateObject方法判断该对象是否是可用的,如果可用则归还到池中,LinkedList容器加一,如果是不可以的则则调用destroyObject方法进行销毁。
    避免泄漏
    • 产生原因
    在一些极端的情况下出现 borrowObject/invalidateObject 没有被调用导致的泄漏问题。
    对象泄漏会导致对象池中的对象数量一直上升,达到设置的上限
    再调用 borrowObject 就会永远等待或者抛出java.util.NoSuchElementException: Timeout waiting for idle object 异常。
    
    
    • 解决策略
    1. 设置抛弃时间
    GenericObjectPool判断一个对象是否泄漏是根据对象最后一次使用或者最后一次borrow的时间进行判断的,
    如果超出了预设的值就会被认为是一个泄漏的对象被清理掉(PooledObjectFactory.destroyObject在这一过程中会被调用)。
    抛弃时间可以通过 AbandonedConfig.setRemoveAbandonedTimeout 进行设置,时间单位是秒
    
    2. 设置了抛弃时间以后还需要打开泄漏清理才会生效。泄漏判断的开启可以通过两种方式
    
    > 从对象池中获取对象的时候进行清理如果当前对象池中少于2个idle状态的对象或者 active数量>最大对象数-3 的时候,
    在borrow对象的时候启动泄漏清理。通过 AbandonedConfig.setRemoveAbandonedOnBorrow 为 true 进行开启。
    
    > 启动定时任务进行清理AbandonedConfig.setRemoveAbandonedOnMaintenance 设置为 true 以后,
    在维护任务运行的时候会进行泄漏对象的清理,可以通过 GenericObjectPool.setTimeBetweenEvictionRunsMillis 设置维护任务执行的时间间隔。
    
    - 使用例子
    GenericObjectPool<PoolObj> pool = new GenericObjectPool<PoolObj>(new MyPooledObjectFactory(),config);
    
    AbandonedConfig abandonedConfig = new AbandonedConfig();
    
    abandonedConfig.setRemoveAbandonedOnMaintenance(true); //在Maintenance的时候检查是否有泄漏
    
    abandonedConfig.setRemoveAbandonedOnBorrow(true); //borrow 的时候检查泄漏
    
    abandonedConfig.setRemoveAbandonedTimeout(10); //如果一个对象borrow之后10秒还没有返还给pool,认为是泄漏的对象
    
    pool.setAbandonedConfig(abandonedConfig);
    
    pool.setTimeBetweenEvictionRunsMillis(5000); //5秒运行一次维护任务
    
    

    透明代理使用demo

    • 初始化定义
    GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
    poolConfig.maxActive = config.getIntAttribute("maxActive", DEFAULT_POOLCONFIG_MAXACTIVE);
    poolConfig.maxIdle = config.getIntAttribute("maxIdle", DEFAULT_POOLCONFIG_MAXIDLE);
    poolConfig.minIdle = config.getIntAttribute("minIdle", DEFAULT_POOLCONFIG_MINIDLE);
    poolConfig.maxWait = config.getIntAttribute("maxWait", DEFAULT_POOLCONFIG_MAXWAIT);
    poolConfig.testOnBorrow = true;
    poolConfig.testOnReturn = true;
    poolConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
    
    port = config.getIntAttribute("port", 80);
    int idleTimeout = config.getIntAttribute("idleTimeout", DEFAULT_IDLE_TIMEOUT);
    int connectionTimeout = config.getIntAttribute("connectionTimeout", DEFAULT_CONNECTION_TIMEOUT);
    int maxResponseLength = config.getIntAttribute("maxResponseLength", DEFAULT_MAX_RESPONSE_LENGTH);
    channelGroup = new DefaultChannelGroup();
    channelPool =new BackendChannelPool(host, port, idleTimeout, connectionTimeout, maxResponseLength, 
        clientSocketChannelFactory, timer, poolConfig,
        new HostBackendHandlerListener() {
            @Override
            public void onExceptionCaught(BackendRequest request,
                            ChannelHandlerContext ctx, ExceptionEvent e) {
                try {
                    if (request == null) {
                        return;
                    }
                    // 如果是 ClosedChannelException 则无需使pool中的连接失效,因为
                    // 创建连接的时候已经添加了连接关闭监听器来处理 参看 BackendConnection
                    if (!(e.getCause() instanceof ClosedChannelException)
                                    && !(e.getCause() instanceof ConnectException)) {
                        BackendConnection connection = request.getConnection();
                        channelPool.invalidateObject(connection);
                    }
                } catch (Exception ex) {
                    LogUtils.error(" invalidate object error ", ex);
                }
            }
    
            @Override
            public void onMessageReceived(BackendRequest request,
                            ChannelHandlerContext ctx, MessageEvent e) {
            }
    
            @Override
            public void onChannelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
                channelGroup.add(ctx.getChannel());
            }
    
            @Override
            public void onMessageProcessed(BackendRequest request,
                            ProxyHttpResponse response, boolean closeConnection,
                            ChannelHandlerContext ctx, MessageEvent e) {
                BackendConnection connection = request.getConnection();
                try {
                    if (closeConnection) {
                        if (connection.isOpen()) {
                            channelPool.invalidateObject(connection);
                        }
                    } else {
                        channelPool.returnObject(connection);
                    }
                } catch (Exception ex) {
                    LogUtils.error(" return object error ", ex);
                }
            }
        },backendExecutor);
        String detectPath = config.getAttribute("detectPath");
        int detectPeriod = config.getIntAttribute("detectPeriod", DEFAULT_DETECT_PERIOD_TIME);
        this.detectTimes = config.getIntAttribute("detectTimes", DEFAULT_DETECT_TIMES);
        if (!StringUtils.isBlank(detectPath)) {
            client = new NettyHttpClient(timer);
            LogUtils.info(this.getName() + " start schedule backend detect " + host + ":" + port + detectPath);
            detectExecutor = Executors.newSingleThreadScheduledExecutor();
            detectExecutor.scheduleAtFixedRate(new BackendDetectThread(host, port, detectPath, client),
                    detectPeriod, detectPeriod, TimeUnit.SECONDS);
        }
    }
    
    
    • 创建对象
    public Object makeObject() throws Exception {
    
    	if(LogUtils.isTraceEnabled()){
        	LogUtils.trace("BackendChannelPool makeObject");
    	}
    
    	// await*() in I/O thread causes a dead lock or sudden performance drop.
    	//  pool.borrowObject() 必须在新的线程中执行
    
    	// Configure the client.
    	final ClientBootstrap cb = new ClientBootstrap(
    			clientSocketChannelFactory);
    	final BlockingQueue<BackendRequest> requestQueue = new LinkedBlockingQueue<BackendRequest>();
    
    	final ChannelPipelineFactory cpf = new ChannelPipelineFactory() {
    
    		@Override
    		public ChannelPipeline getPipeline() throws Exception {
    			// Create a default pipeline implementation.
    			final ChannelPipeline pipeline = Channels.pipeline();
    
    			pipeline.addLast("timeout", new ProxyIdleStateHandler(timer, 0, 0, idleTimeout, TimeUnit.MILLISECONDS));
    			pipeline.addLast("decoder", new ProxyHttpResponseDecoder());
    			pipeline.addLast("aggregator", new ProxyHttpChunkAggregator(maxResponseLength));
    
    			final BackendRelayingHandler handler = new BackendRelayingHandler(
    					handlerListener,requestQueue,backendExecutor);
    
    			final BackendRequestEncoder encoder = new BackendRequestEncoder(requestQueue);
    			pipeline.addLast("encoder", encoder);
    			pipeline.addLast("handler", handler);
    			return pipeline;
    		}
    	};
    
    	// Set up the event pipeline factory.
    	cb.setPipelineFactory(cpf);
    	//TODO more option config.
    	cb.setOption("connectTimeoutMillis", connectionTimeout * 1000);
    
    	ChannelFuture future = cb.connect(new InetSocketAddress(host,
    			port));
    	if(LogUtils.isDebugEnabled()){
    		LogUtils.debug("ClientChannelObjectFactory.makeObject ChannelFuture: "+host+":"+port);
    	}
    	future = future.await();
    	if(future.isCancelled()){
    		throw new ConnectTimeoutException("request cancelled.");
    	}else if(!future.isSuccess()){
    		throw new ConnectTimeoutException(future.getCause());
    	}else{
    		return new BackendConnection(future.getChannel());
    	}
    }
    
    

    重要优化点

    • connectionPool.setMaxActive(maxActive); connectionPool.setMaxIdle(maxActive); 成对配置

    • 设置maxWait connectionPool.setMaxWait(maxWait);

      不设置会导致当被依赖的服务由于某些故障(如机器资源被某进程大量占用)而响应极慢时,会有大量线程blocked在borrowObject的逻辑,最终导致resin线程耗尽,服务卡死,用户请求被拒绝

      因此需要对maxWait进行设置,且设置的时间不宜过大(高吞吐时仍有可能导致web卡死),也不宜过小(可能导致较多的请求失败)

      基本原则: qt<N, 其中q为服务最大吞吐(请求/s), t为设置的maxWait时间(s), N为resin的最大线程数 resin的线程数当前为512, 预估最大吞吐为100, 因此有t<N/q=512/100=5.12 我们将其配置为3s(即3000ms), 从而当该对象池中的对象出现异常时,仍可扛住512/3约为170qps的压力

    展开全文
  • Unity3D框架学习_对象池对象池管理

    千次阅读 2019-04-14 20:41:04
    Unity3D框架学习_对象池对象池管理 目录 1、博客介绍 2、内容 (1)ObjectPoolContainer 对象容器 (2)ObjectPool 单一对象池 (3)PoolManager 对象池管理 3、推送 4、结语 1、博客介绍 本篇博客介绍...

                              Unity3D框架学习_对象池和对象池管理


    目录

    1、博客介绍

    2、内容

    (1)ObjectPoolContainer 对象容器

    (2)ObjectPool 单一对象池

    (3)PoolManager 对象池管理

    3、推送

    4、结语


    1、博客介绍

            本篇博客介绍Unity对象池的管理,改自github某工程,结尾会推送,对象池没什么特别好说的了就是实例对象,释放对象,博主这篇写的很简单,读者直接看博主的工程就一目了然了,博客内不再书写代码,工程注释和结构都很清晰,配的还有流程图,工程推送在结尾博主的github。


    2、内容

    (1)ObjectPoolContainer 对象容器

    该脚本包含了实例对象和该对象的使用状态

    (2)ObjectPool 单一对象池

             对象池内包含了,储存对象容器的链表,正在使用的对象的字典,池子名字,获取对象实例的方法Get(),释放对象的方法Release()。

    (3)PoolManager 对象池管理

           对象池管理脚本,对象池会自动挂载在PoolManager空节点下,没有自动创建,生成物释放后也放置在PoolManager下,字典储存了不同的对象池, 可以设置刷新时间RefreshTime来定时刷新池子,会删除不活跃的池子。


    3、推送

    博主github:https://github.com/KingSun5/UnityPool

    学习借鉴:https://github.com/thefuntastic/unity-object-pool


    4、结语

    学习使人进步,最近好困呀,春困呀,博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。

           QQ交流群:806091680(Chinar)

           该群为CSDN博主Chinar所创,推荐一下!我也在群里!

           本文属于原创文章,转载请著名作者出处并置顶!!!!!

    展开全文
  • 对象池管理类

    2018-10-29 15:31:07
    Unity中对象池一般都是关闭和再打开的原理,鉴于有的程序员写的对象池非常复杂且不易理解,但是原理还是那样。所以我这里自己整理了一个对象池管理类,只有两个脚本即可以实现所有gameObject通用,里边还有《示例场景...
  • 众所周知,游戏开发中内存和性能一直是影响用户游戏体验的至关重要的两个因素,这次说一说对象池的概念。 对象池意义是将游戏中反复创建销毁的对象进行多次利用,从而避免大量对象的销毁与创建而造成CPU的负担。...
  • 对象池具有自动返回和附加/分离语义的线程安全对象池对象池的目标是重用昂贵的内存来分配对象池具有自动返回和附加/分离语义的线程安全对象池对象池是重用昂贵的分配对象或频繁分配的对象的用法。[dependencies] ...
  • 使用对象池 在运行时进行节点的创建(cc.instantiate)和销毁(node.destroy)操作是非常耗费性能的,因此我们在比较复杂的场景中,通常只有在场景初始化逻辑(onLoad)中才会进行节点的创建,在切换场景时才会进行节点...
  • python对象池

    千次阅读 2018-07-17 16:57:52
    python对象池 python中,一切皆为对象 id方法的返回值就是对象的内存地址。 is运算符,如果引用的是同一个对象则返回true,x is y类似 id(x) == id(y)  小整数对象池 [-5, 256] 这些小整数被定义在了一个整数...
  • Unity3D 对象池插件

    2019-01-07 17:43:54
    非常好用的Unity3D对象池插件,内含使用文档,简单易上手
  • Unity对象池PoolManager6.0最新版本Unity对象池PoolManager6.0最新版本Unity对象池PoolManager6.0最新版本Unity对象池PoolManager6.0最新版本
  • 对象池pool项目工程.unitypackage对象池pool项目工程.unitypackage对象池pool项目工程.unitypackage
  • C++对象池源码示例

    2020-05-28 16:04:10
    所谓对象池就是有很多对象的池子,其实也就是开始创建大量的对象放在一个池子里面,采用对象池的方式,会使对象在申请和释放时更加的高效和方便
  • Unity对象池技术

    千次阅读 2017-03-02 14:00:31
    引入对象池技术,可以将暂时不需要用到游戏对象放在对象池(缓冲区),当需要使用到时再从对象池中提取 这里我简单学习了下关于对象池,现在分享出来,写下自己的对对象池的理解 using UnityEngine; using ...
  • Unity对象池

    2017-02-26 21:44:03
    我正在写的《 Unity编程标准导引》一书中的章节。 介绍了一个通用的Unity对象池的写法。用于GameObject的回收重用处理。 具体详细内容请参考我的博客:http://blog.csdn.net/andrewfan
  • C#自定义对象池

    2014-02-24 15:46:44
    C# 实现自定义对象池,在数据库操作的时候,频繁的创建、关闭连接,消耗许多资源。自定义一个对象池,在对象池中始终保留几个可用连接,不用每次都重新创建。 初始版本,目前还不知道性能咋样。
  • 对象池通过对象复用的方式来避免重复创建对象,它会事先创建一定数量的对象放到池中,当用户需要创建对象的时候,直接从对象池中获取即可,用完对象之后再放回到对象池中,以便复用。这种方式避免了重复创建耗时或耗...
  • unity对象池之引用技术

    千次阅读 多人点赞 2020-06-16 20:39:45
    使用引用技术的前提是你得使用对象池,对于对象池这个东西,我就不作详细介绍了,对象池用来存放会被经常使用的东西,当需要用的时候就从对象池里取出来用,不需要用时就将它放进池子里。那么问题来了,对象池里面的...
  • 对象池机制

    千次阅读 2015-04-16 10:07:38
    1.什么时候需要创建对象池  当我们频繁创建删除大量对象的时候,对象的创建删除所造成的开销就不容小觑了。为了提高性能,我们往往需要实现一个对象池作为Cache:使用对象时,它从池中提取。用完对象时,它放回池...
  • Unity 对象池

    千次阅读 多人点赞 2018-05-04 17:14:26
    概念我们先讲讲对象池是什么,有什么用。在游戏的制作过程中,我们可能会碰到这样的情况,就像现在最火的吃鸡游戏一样,我们有一把枪,开枪的时候射出子弹。每个子弹即一个对象,正常情况,我们的处理方式可能会是,...
  • unity中的对象池应用

    2019-04-26 19:14:44
    1.虽然对象池可以优化对象利用率,但是对象池也不能无限地存储对象,这样对于内存占用也是急剧增加,应该通过限制池子上限,并通过统计获取使用频率较低的对象并剔除,从而动态地收缩对象池; 2.对于重复使用的对象...
  • 对象池模式经常用在频繁创建、销毁对象(并且对象创建、销毁开销很大)的场景,比如数据库连接池、线程池、任务队列池等。本代码简单,没有限制对象池大小
  • Android 对象池 谨慎和智能地使用系统资源对 Android 来说至关重要。 过度消耗堆内存会带来OutOfMemory异常和无数次遇到垃圾收集器(GC)。 GC会占用 UI 线程的宝贵时间,并且会导致丢弃 UI 帧,从而提供糟糕的用户...
  • Netty对象池 Recycler

    千次阅读 2021-03-05 12:31:00
    Netty对象池 Recycler 对于为什么要使用对象池,肯定是提高性能啊! 对象的创建,回收,再创建;很耗损jvm性能的,所以就有了对象池的概念,Netty通过Recycler管理对象的创建与回收,而在对象回收时,也不是真正的...
  • 一个封装好的对象池小框架,子弹的无线复用,注释详细可以增加新功能

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 494,203
精华内容 197,681
关键字:

对象池