• 通用池化框架GenericObjectPool性能测试


    之前写过了- 通用池化框架commons-pool2实践以及通用池化框架实践之GenericKeyedObjectPool。接下来我就对这个池化框架进行性能测试。首先呢就是因为这个池化技术必需要有足够的性能,不然通过池化技术优化的部分,在较高QPS的性能测试中,对象池可能成为本机瓶颈。

    硬件软件配置

    硬件就是我自己的电脑,型号MacBook Pro (16-inch, 2019),配置6C16G。因为这次测试并没有测试到性能极限,在测试方案设计的前阶段已经有了相对明显的结论了。

    软件方面,还是Groovy,默认Java进程启动参数。对象池化的设置后面可以在代码中看到,经过我的测试,只要对象池中还有空闲对象就足够满足当前性能。因为我本次用的是固定线程模型,所以换算过来就是对象数大于线程数即可。

    测试前准备

    测试分成了两部分:无等待归还对象、有等待归还对象。因为无等待归还对象测试过程中,结论出现的太早也太明显了。

    可池化对象

        /**
         * 可池化对象
         */
        private static class FunTesterPooled {
    
            String name
    
            int age
    
        }
    
    

    池化工场

        /**
         * 池化工厂
         */
        private static class FunFactory extends BasePooledObjectFactory<FunTesterPooled> {
    
    
            @Override
            FunTesterPooled create() throws Exception {
                return new FunTesterPooled()
            }
    
            @Override
            PooledObject<FunTesterPooled> wrap(FunTesterPooled obj) {
                return new DefaultPooledObject<FunTesterPooled>(obj)
            }
    
            @Override
            void destroyObject(PooledObject<FunTesterPooled> p, DestroyMode destroyMode) throws Exception {
                p.getObject().setName("") //回收资源
                super.destroyObject(p, destroyMode)
            }
        }
    

    对象池

        static def initPool() {
            def config = new GenericObjectPoolConfig<FunTesterPooled>()
            config.setMaxIdle(10)
            config.setMinIdle(2)
            config.setMaxTotal(thread * 2)
            return new GenericObjectPool<FunTesterPooled>(new FunFactory(), config)
        }
    

    性能测试用例

        static GenericObjectPool<FunTesterPooled> pool
    
        static def desc = "池化框架性能测试"
    
        static int times = 3000000
    
        static int thread = 2
    
        public static void main(String[] args) {
            this.pool = initPool()
            ThreadBase.COUNT = true
            RUNUP_TIME = 0
            def barrier = new CyclicBarrier(thread + 1)
            POOL_SIZE = thread
            def borrows = []
            thread.times {
                fun {
                    borrows << pool.borrowObject()
                    barrier.await()
                }
            }
            barrier.await()
            borrows.each {
                pool.returnObject(it)
            }
            output("对象创建完毕 创建数量${pool.getNumIdle()}")
            new Concurrent(new FunTester(), thread, desc).start()
            pool.close()
        }
    
        private static class FunTester extends FixedThread {
    
    
            FunTester() {
                super(null, times, true)
            }
    
            @Override
            protected void doing() throws Exception {
                pool.returnObject(pool.borrowObject())
            }
    
            @Override
            FunTester clone() {
                return new FunTester()
            }
        }
    
    

    其中往对象池中添加对象的时候,一开始我思路有点偏,所以想了一个java.util.concurrent.CyclicBarrier的方案。其实我们直接可以使用官方提供的org.apache.commons.pool2.ObjectPool#addObjects方法实现,代码非常简单,一行搞定pool.addObjects(thread)

    测试结果

    无等待

    线程数 执行次数(万) QPS
    1 300 1876172
    2 300 1852364
    5 300 1533912
    10 300 1524538
    10 100 1571623
    20 100 1568692

    可以看出,QPS非常高,足够满足线性能测试需求。

    等待

    使用了休眠2ms的配置。

    线程数 执行次数(k) 单线程QPS
    20 10 410
    50 10 406
    100 5 406
    200 2 404
    300 2 403
    400 2 403
    500 2 262
    800 2 143
    1000 2 114

    看来还是有瓶颈,在并发线程超过400多以后,这个平均单线程QPS会下降会多。猜测可能是org.apache.commons.pool2.impl.LinkedBlockingDequejava.util.concurrent.atomic.AtomicLong两个类的性能瓶颈。可以参考之前做过的Java&Go高性能队列之LinkedBlockingQueue性能测试,虽然不一样可以参考。

    虽然后面性能有所下降,瓶颈也在10万以上,也算是满足部分性能测试需求吧。后面我对com.funtest.PoolTest#GenericKeyedObjectPool对象池的性能,敬请期待。

  • 相关阅读:
    ConcurrentHashMap源码分析
    HashMap源码与相关面试题
    字符串学习笔记(三)---- StringBuilder
    字符串学习笔记(二)---- StringBuffer
    Vue一些基本操作技巧
    PHP代码及命名规范
    Js返回顶部的方法
    linux下镜像网站的几种方法
    单例模式示例
    工厂模式和IOC练习
  • 原文地址:https://www.cnblogs.com/FunTester/p/16339085.html
Copyright © 2020-2023  润新知