北大青鸟分享Java初期学者程序性能容易的问题测试

北大青鸟分享Java初期学者程序性能容易的问题测试,第1张

1、介绍

在开发中,性能测试是设计初期容易忽略的问题,开发人员会为了解决一个问题而“不择手段”,所参与的项目中也遇到了类似问题,字符串拼接、大量的调用和数据库访问等等都对系统的性能产生了影响,可是大家不会关心这些问题,“CPU速度在变快”,“内存在变大”,并且,“好像也没有那么慢吧”。

有很多商业的性能测试软件可供使用,如Jprofiler、JProbeProfiler等,但在开发当中显得有些遥远而又昂贵。

2、目标

本文将讲述如何利用语言本身提供的方法在开发中进行性能测试,找到系统瓶颈,进而改进设计;并且在尽量不修改测试对象的情况下进行测试。

3、预备知识

面向对象编程通过抽象继承采用模块化的来求解问题域,但是模块化不能很好的解决所有问题。有时,这些问题可能在多个模块中都出现,像日志功能,为了记录每个方法进入和离开时的信息,你不得不在每个方法里添加log("insomemethod")等信息。如何解决这类问题呢将这些解决问题的功能点散落在多个模块中会使冗余增大,并且当很多个功能点出现在一个模块中时,代码变的很难维护。因此,AOP(AspectOrientedProgramming)应运而生。如果说OO(AobjectOrientedProgramming)关注的是一个类的垂直结构,那么AOP是从水平角度来看待问题。

动态代理类可以在运行时实现若干接口,每一个动态代理类都有一个Invocationhandler对象与之对应,这个对象实现了InvocationHandler接口,通过动态代理的接口对动态代理对象的方法调用会转而调用Invocationhandler对象的invoke方法,通过动态代理实例、方法对象和参数对象可以执行调用并返回结果。

说到AOP,大家首先会想到的是日志记录、权限和事务,是的,AOP是解决这些问题的好办法。

性能测试主要包括以下几个方面:

计算性能:可能是人们首先关心的,北大青鸟认为简单的说就是执行一段代码所用的时间

内存消耗:程序运行所占用的内存大小

启动时间:从你启动程序到程序正常运行的时间

可伸缩性(scalability)

用户察觉性能(perceivedperformance):不是程序实际运行有多快,而是用户感觉程序运行有多快

  代理模式( )

以上代码分别生成了 种代理 并对生成的代理类进行高频率的调用 最后输出各个代理类的创建耗时 动态类类名和方法调用耗时 结果如下

createJdkProxy:

JdkProxy class:$Proxy

callJdkProxy:

createCglibProxy:

CglibProxy class:$javatuning ch proxy IDBQuery$$EnhancerByCGLIB$$b a bbf

callCglibProxy:

createJavassistDynProxy:

JavassistDynProxy class:javatuning ch proxy IDBQuery_$$_javassist_

callJavassistDynProxy:

createJavassistBytecodeDynamicProxy:

JavassistBytecodeDynamicProxy class:javatuning ch proxy IDBQueryJavaassistBytecodeProxy

callJavassistBytecodeDynamicProxy:

可以看到 JDK的动态类创建过程最快 这是因为在这个内置实现中defineClass()方法被定义为native实现 故性能高于其他几种实现 但在代理类的函数调用性能上 JDK的动态代理就不如CGLIB和Javassist的基于动态代码的代理 而Javassist的基于代理工厂的代理实现 代理的性能质量最差 甚至不如JDK的实现 在实际开发应用中 代理类的方法调用频率通常要远远高于代理类的实际生成频率(相同类的重复生成会使用cache) 故动态代理对象的方法调用性能应该作为性能的主要关注点

注意 就动态代理的方法调用性能而言 CGLIB和Javassist的基于动态代码的代理都优于JDK自带的动态代理 此外 JDK的动态代理要求代理类和真实主题都实现同一个接口 而CGLIB和Javassist没有强制要求

Hibernate中代理模式的应用

用代理模式实现延迟加载的一个经典应用就在Hibernate框架中 当Hibernate加载实体bean时 并不会一次性将数据库所有的数据都装载 默认情况下 它会采取延迟加载的机制 以提高系统的性能 Hiberante中的延迟加载主要有两种 一是属性的延迟加载 二是关联表的延时加载 这里以属性的延迟加载为例 简单阐述Hibernate是如何使用动态代理的

假定有用户模型

public class User implements java io Serializable {

private Integer id;

private String name;

private int age;

//省略getter和setter

使用以下代码 通过Hibernate加载一条User信息

public static void main(String[] args) throws SecurityException

NoSuchFieldException

IllegalArgumentException

IllegalAccessException {

//从数据库载入ID为 的用户

User u=(User)HibernateSessionFactory getSession() load(User class )

//打印类名称

System out println( Class Name: +u getClass() getName())

//打印父类名称

System out println( Super Class Name: +u getClass() getSuperclass()

getName())

//实现的所有接口

Class[] ins=u getClass() getInterfaces()

for(Class cls:ins){

System out println( interface: +cls getName())

}

System out println(u getName())

}

       返回目录 Java程序性能优化 让你的Java程序更快 更稳定

编辑推荐

       Java程序设计培训视频教程

       J EE高级框架实战培训视频教程

       J ME移动开发实战教学视频

Visual C++音频/视频技术开发与实战

Oracle索引技术

lishixinzhi/Article/program/Java/gj/201311/27829

  单例模式( )

单例模式是设计模式中使用最为普遍的模式之一 它是一种对象创建模式 用于产生一个对象的具体实例 它可以确保系统中一个类只产生一个实例 在Java语言中 这样的行为能带来两大好处

( )对于频繁使用的对象 可以省略创建对象所花费的时间 这对于那些重量级对象而言 是非常可观的一笔系统开销

( )由于new *** 作的次数减少 因而对系统内存的使用频率也会降低 这将减轻GC压力 缩短GC停顿时间

因此对于系统的关键组件和被频繁使用的对象 使用单例模式便可以有效地改善系统的性能

单例模式的参与者非常简单 只有单例类和使用者两个 如表 所示

表   单例模式角色

它的基本结构如图 所示

图   单例模式类图

单例模式的核心在于通过一个接口返回唯一的对象实例 一个简单的单例实现如下

public class Singleton {

private Singleton(){

System out println( Singleton is create ) //创建单例的过程可能会比较慢

}

private static Singleton instance = new Singleton()

public static Singleton getInstance() {

return instance;

}

}

注意代码中的重点标注部分 首先单例类必须要有一个private访问级别的构造函数 只有这样 才能确保单例不会在系统中的其他代码内被实例化 这点是相当重要的 其次 instance成员变量和getInstance()方法必须是static的

注意 单例模式是非常常用的一种结构 几乎所有的系统中都可以找到它的身影 因此 希望读者可以通过本节 了解单例模式的几种实现方式及其各自的特点

这种单例的实现方式非常简单 而且十分可靠 它唯一的不足仅是无法对instance实例做延迟加载 假如单例的创建过程很慢 而由于instance成员变量是static定义的 因此在JVM加载单例类时 单例对象就会被建立 如果此时 这个单例类在系统中还扮演其他角色 那么在任何使用这个单例类的地方都会初始化这个单例变量 而不管是否会被用到 比如单例类作为String工厂 用于创建一些字符串(该类既用于创建单例Singleton 又用于创建String对象)

public class Singleton {

private Singleton() {

System out println( Singleton is create )

//创建单例的过程可能会比较慢

}

private static Singleton instance = new Singleton()

public static Singleton getInstance() {

return instance;

}

public static void createString(){      //这是模拟单例类扮演其他角色

System out println( createString in Singleton )

}

}

       返回目录 Java程序性能优化 让你的Java程序更快 更稳定

编辑推荐

       Java程序设计培训视频教程

       J EE高级框架实战培训视频教程

       J ME移动开发实战教学视频

Visual C++音频/视频技术开发与实战

Oracle索引技术

lishixinzhi/Article/program/Java/gj/201311/27837

四 ASP NET缓存API 

在写应用程序之前 你要做的第一件事是让应用程序最大化的利用ASP NET的缓存功能  

如果你的组件是要在Asp net应用程序中运行 你只要把System Web dll引用到你的项目中就可以了 然后用>

您好,很高兴能帮助您,

您可以使用

Gacutilexe

将强名称程序集添加到全局程序集缓存,并查看全局程序集缓存的内容。

注意Gacutilexe

只用于开发,不应用于将产品程序集安装到全局程序集缓存中。

使用

Microsoft

Windows

Installer

20。

这是将程序集添加到全局程序集缓存的最常用方法,建议采用。此安装程序可提供全局程序集缓存中程序集的引用计数,还具有其他优点。

使用

NET

Framework

SDK

提供的名为

程序集缓存查看器

(Shfusiondll)

Windows

外壳扩展。

使用该外壳扩展可将程序集拖放到全局程序集缓存中。

使用

NET

Framework

配置工具

(Mscorcfgmsc)。

使用

可以查看全局程序集缓存并将新的程序集添加到该缓存。

你的采纳是我前进的动力,还有不懂的地方,请你继续“追问”!

如你还有别的问题,可另外向我求助;答题不易,互相理解,互相帮助!

  代理模式( )

在以上代码中 使用CtField make()方法和CtNewMehod make()方法在运行时生成了代理类的字段和方法 这些逻辑由Javassist的CtClass对象处理 将Java代码转换为对应的字节码 并生成动态代理类的实例

注意 与静态代理相比 动态代理可以很大幅度地减少代码行数 并提升系统的灵活性

在Java中 动态代理类的生成主要涉及对ClassLoader的使用 这里以CGLIB为例 简要阐述动态类的加载过程 使用CGLIB生成动态代理 首先需要生成Enhancer类实例 并指定用于处理代理业务的回调类 在Enhancer create()方法中 会使用DefaultGeneratorStrategy Generate()方法生成动态代理类的字节码 并保存在byte数组中 接着使用ReflectUtils defineClass()方法 通过反射 调用ClassLoader defineClass()方法 将字节码装载到ClassLoader中 完成类的加载 最后使用ReflectUtils newInstance()方法 通过反射 生成动态类的实例 并返回该实例 无论使用何种方法生成动态代理 虽然实现细节不同 但主要逻辑都如图 所示

图   实现动态代理的基本步骤

前文介绍的几种动态代理的生成方法 性能有一定差异 为了能更好地测试它们的性能 去掉DBQuery类中的sleep()代码 并使用以下方法测试

public static final int CIRCLE= ;

public static void main(String[] args) throws Exception {

IDBQuery d=null;

long begin=System currentTimeMillis()

d=createJdkProxy()                      //测试JDK动态代理

System out println( createJdkProxy: +(System currentTimeMillis() beg    in))

System out println( JdkProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callJdkProxy: +(System currentTimeMillis() begin    ))

begin=System currentTimeMillis()

d=createCglibProxy()                    //测试CGLIB动态代理

System out println( createCglibProxy: +(System currentTimeMillis() b    egin))

System out println( CglibProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callCglibProxy: +(System currentTimeMillis() beg    in))

begin=System currentTimeMillis()

d=createJavassistDynProxy()             //测试Javaassist动态代理

System out println( createJavassistDynProxy: +(System currentTimeMil    lis() begin))

System out println( JavassistDynProxy class: +d getClass() getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callJavassistDynProxy: +(System currentTimeMilli    s() begin))

begin=System currentTimeMillis()

d=createJavassistBytecodeDynamicProxy()     //测试Javassist动态代理

System out println( createJavassistBytecodeDynamicProxy: +(System cu    rrentTimeMillis() begin))

System out println( JavassistBytecodeDynamicProxy class: +d getClass()

getName())

begin=System currentTimeMillis()

for(int i= ;i<CIRCLE;i++)

d request()

System out println( callJavassistBytecodeDynamicProxy: +(System curr    entTimeMillis() begin))

}

       返回目录 Java程序性能优化 让你的Java程序更快 更稳定

编辑推荐

       Java程序设计培训视频教程

       J EE高级框架实战培训视频教程

       J ME移动开发实战教学视频

Visual C++音频/视频技术开发与实战

Oracle索引技术

lishixinzhi/Article/program/Java/gj/201311/27830

以上就是关于北大青鸟分享Java初期学者程序性能容易的问题测试全部的内容,包括:北大青鸟分享Java初期学者程序性能容易的问题测试、Java程序性能优化-代理模式(6)、Java程序性能优化-单例模式(1)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9489973.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存