`
san_yun
  • 浏览: 2663603 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

jython测试记录

 
阅读更多
jython30个并发性能下降比较明显,有超时现象:
引用

<urlopen error timed out> /napi/blog/detail/?blog_id=45756664
cost:2.00654006004
cost:1.49004387856
cost:0.0366380214691
cost:1.3818898201
cost:1.11271309853
cost:0.0867030620575
cost:0.51217007637
<urlopen error timed out> /napi/blog/detail/?blog_id=45705708


jstack看了一下大量被IdImpl.id()BLOCKED了
引用

"catalina-exec-111" daemon prio=10 tid=0x00002aaac0844000 nid=0x1a91 waiting for monitor entry [0x0000000052436000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at org.python.core.IdImpl.id(IdImpl.java:76)
        - waiting to lock <0x0000000704407ec8> (a org.python.core.IdImpl)
        at org.python.core.Py.id(Py.java:1830)
        at org.python.core.__builtin__.id(__builtin__.java:667)
        at org.python.core.BuiltinFunctions.__call__(__builtin__.java:82)
        at org.python.core.PyObject.__call__(PyObject.java:407)
        at copy$py._keep_alive$13(/data1/duitang/dist/sys/jython/Lib/copy.py:281)
        at copy$py.call_function(/data1/duitang/dist/sys/jython/Lib/copy.py)
        at org.python.core.PyTableCode.call(PyTableCode.java:165)
        at org.python.core.PyBaseCode.call(PyBaseCode.java:149)
        at org.python.core.PyFunction.__call__(PyFunction.java:357)
        at copy$py.deepcopy$7(/data1/duitang/dist/sys/jython/Lib/copy.py:194)
        at copy$py.call_function(/data1/duitang/dist/sys/jython/Lib/copy.py)
        at org.python.core.PyTableCode.call(PyTableCode.java:165)
        at org.python.core.PyBaseCode.call(PyBaseCode.java:301)
        at org.python.core.PyFunction.function___call__(PyFunction.java:406)
        at org.python.core.PyFunction.__call__(PyFunction.java:401)
        at django.db.models.sql.query$py.clone$18(/duitang/dist/sys/tomcat/webapps/ROOT/WEB-INF/lib-python/Lib/site-packages/django/db/models/sql/query.py:291)
        at django.db.models.sql.query$py.call_function(/duitang/dist/sys/tomcat/webapps/ROOT/WEB-INF/lib-python/Lib/site-packages/django/db/models/sql/query.py)
        at org.python.core.PyTableCode.call(PyTableCode.java:165)
        at org.python.core.PyBaseCode.call(PyBaseCode.java:301)
        at org.python.core.PyBaseCode.call(PyBaseCode.java:127)
        at org.python.core.PyFunction.__call__(PyFunction.java:347)
        at org.python.core.PyMethod.__call__(PyMethod.java:109)
        at django.db.models.query$py._clone$47(/duitang/dist/sys/tomcat/webapps/ROOT/WEB-INF/lib-python/Lib/site-packages/django/db/models/query.py:762)
        at django.db.models.query$py.call_function(/duitang/dist/sys/tomcat/webapps/ROOT/WEB-INF/lib-python/Lib/site-packages/django/db/models/query.py)
        at org.python.core.PyTableCode.call(PyTableCode.java:165)
        at org.python.core.PyBaseCode.call(PyBaseCode.java:301)
        at org.python.core.PyBaseCode.call(PyBaseCode.java:127)
        at org.python.core.PyFunction.__call__(PyFunction.java:347)


看了jython的实现大概明白了,他自己实现了一个WeakIdentityMap用来做cache,但不是线程安全,就粗暴的在 public synchronized long id(PyObject o)方法前面直接加上 synchronized。

package org.python.core;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Map;

import org.python.util.Generic;

public class IdImpl {

    private WeakIdentityMap idMap = new WeakIdentityMap();

    private long sequentialId;

    public synchronized long id(PyObject o) {
        Object javaProxy = o.getJavaProxy();
        if (javaProxy != null) {
            return java_obj_id(javaProxy);
        } else {
            return java_obj_id(o);
        }
    }

    public String idstr(PyObject o) {
        return String.format("0x%x", id(o));
    }

    public synchronized long java_obj_id(Object o) {
        Long cand = (Long)idMap.get(o);
        if (cand == null) {
            long new_id = ++sequentialId;
            idMap.put(o, new_id);
            return new_id;
        }
        return cand.longValue();
    }
}


看了大概明白了,他自己实现了一个WeakIdentityMap用来做cache,但不是线程安全,就粗暴的在方法前面直接加上 synchronized。

这是他自己实现的WeakIdentityMap:
  public static class WeakIdentityMap {

        private transient ReferenceQueue<Object> idKeys = new ReferenceQueue<Object>();

        private Map<WeakIdKey, Object> objHashcodeToPyId = Generic.map();

        @SuppressWarnings("element-type-mismatch")
        private void cleanup() {
            Object k;
            while ((k = idKeys.poll()) != null) {
                objHashcodeToPyId.remove(k);
            }
        }

        private class WeakIdKey extends WeakReference<Object> {
            private final int hashcode;

            WeakIdKey(Object obj) {
                super(obj, idKeys);
                hashcode = System.identityHashCode(obj);
            }

            @Override
            public int hashCode() {
                return hashcode;
            }

            @Override
            public boolean equals(Object other) {
                Object obj = get();
                if (obj != null) {
                    return obj == ((WeakIdKey)other).get();
                } else {
                    return this == other;
                }
            }
        }

        // Used by test_jy_internals
        public int _internal_map_size() {
            return objHashcodeToPyId.size();
        }

        public void put(Object key, Object val) {
            cleanup();
            objHashcodeToPyId.put(new WeakIdKey(key), val);
        }

        public Object get(Object key) {
            cleanup();
            return objHashcodeToPyId.get(new WeakIdKey(key));
        }

        public void remove(Object key) {
            cleanup();
            objHashcodeToPyId.remove(new WeakIdKey(key));
        }

    }


分享到:
评论

相关推荐

    Jython远程调试

    3. **创建测试用例**:编写一个JUnit测试用例,用以启动Jython程序并设置断点。例如,创建一个`test`方法,通过`PythonInterpreter`执行Jython脚本,并在适当位置设置断点。 ```java @Test public void test() { /...

    New Riders - Jython for Java Programmers.rar_Riders_jython

    10. **测试驱动开发(TDD)**:Jython可以与JUnit等Java测试框架结合,支持TDD实践,促进代码质量。 通过《Jython for Java Programmers》这本书,读者将学习如何利用Jython进行Java开发,理解两者之间的交互,以及...

    应用MaxQ做Web功能测试

    它包含一个记录Jython测试脚本的HTTP代理,一个用于回放测试的命令行实用程序。代理记录器自动存储提交到表单的变量。 简介:MaxQ是一个开源的Web功能测试工具。它包含...

    imagrium:Imagrium 是一个基于图像识别方法的移动应用跨平台测试的 Jython 框架(Android 和 iOS 应用测试自动化软件)

    关于Imagrium是一个 Jython 框架,用于基于图像识别方法(并根据 MIT 许可条款分发)移动应用程序的跨平台测试。 该框架的核心原则(反映在其设计中)是: 在平台之间共享测试代码库。 换句话说,功能测试应该与应用...

    monkey压力测试工具

    6. **脚本化测试**:Monkey测试支持自定义脚本,通过Jython或其他脚本语言编写特定的测试逻辑,提高测试的针对性。 7. **MonkeyRunner**:MonkeyRunner是Android SDK中的一个组件,它提供了一个Python接口来编写...

    web压力测试工具介绍

    1. **Grinder**:Grinder是一款基于JVM的开源压力测试框架,它支持Jython脚本引擎,可以通过HTTP代理进行HTTP测试。Grinder的优势在于它允许程序员深入测试应用的各个层次,而不只是表面的响应时间。 2. **Pylot**...

    开源压力测试工具.pdf

    1. Grinder:Grinder是一款基于JVM的开源负载测试框架,它支持Jython脚本编写测试脚本,通过HTTP代理管理HTTP测试。Grinder的目标用户是有深入技术理解的开发者,因为它允许对应用的内部层次进行测试,而不仅仅是...

    Console4Jython-开源

    3. **加载和运行脚本**:作为一个独立的应用程序,Console4Jython支持直接加载和运行Jython脚本文件,使得开发和测试Jython程序变得更加便捷。用户无需通过命令行或者集成开发环境(IDE)来执行代码,只需在控制台中...

    Grinder入门介绍

    - **Worker 进程**:解释执行 Jython 测试脚本,并使用多个工作线程来执行测试任务。 - **Agent 进程**:管理 Worker 进程。 - **控制台(Console)**:协调其他进程的工作,收集并展示统计信息,同时提供脚本编辑和...

    eclipse和pydev以及python安装部署说明.docx

    - 编写Jython测试类并运行。 总结:本文档详细阐述了在Windows XP环境下安装Python 2.6及其相关依赖,包括Setuptools和MySQL驱动,并提供了Eclipse与PyDev的集成配置方法,以便进行Python自动化测试框架的开发。...

    MonkeyRunner--从环境构建

    录制回放功能通过脚本录制功能实现,允许测试人员记录操作序列并生成mr脚本文件。之后,可以使用回放功能来重复执行先前的操作序列。 在编写MonkeyRunner测试脚本时,尽管使用的是Python语法,但实际执行是通过...

    grinder的使用步骤和运行命令

    Proxy用于记录用户交互,Agent在目标系统上生成负载,Controller协调和控制整个测试过程。 三、运行步骤 1. 启动Proxy:运行`grinder_proxy`命令,这将启动一个监听特定端口(默认为6314)的代理服务器,记录用户...

    jmeter 命令行运行解析插件

    其中,`-n`表示非GUI模式,`-t`指定要运行的JMX测试计划文件,`-l`用于指定结果文件,`-j`则用于记录JMeter的运行日志。这种方式可以避免GUI对系统资源的影响,特别是在大量并发测试时。 接下来,我们来看插件的...

    robotframework2.7.5

    7. **插件和集成**:Robot Framework可以与各种工具集成,如Selenium WebDriver用于Web UI测试,Appium for移动应用测试,Jython/IronPython支持在Java/.NET环境中运行。 8. **版本控制**:使用版本控制系统(如Git...

    RobotFramework-DatabaseLibrary.rar_robotframework

    它提供了一系列关键字,方便测试人员执行SQL查询、操作数据库记录、验证数据完整性和一致性等任务。这个库适用于各种关系型数据库,如MySQL、PostgreSQL、Oracle、SQL Server等,通过适配器机制与不同的数据库管理...

    pop800在线工具

    pop800在线工具,免费在的三纯正Grinder是一个负载测试框架,通过Jython来编写测试脚本,基于HTTP的测试可以由浏览器来记录整个要测试的过程。 关键特性: 泛型测试方法 灵活的测试脚本编写

Global site tag (gtag.js) - Google Analytics