如果大家使用的是maven工程Q那么现?/span>pom文g中加?/span>perf4j的依赖?/span>
<dependency>
<groupId>org.perf4j</groupId>
<artifactId>perf4j</artifactId>
<version>0.9.16</version>
<scope>compile</scope>
</dependency>
如果用的是普通工E,那么直接下蝲jar包放?/span>lib目录下即可?/span>
例子Q?/span>
package com.baowu.per4j;
import org.perf4j.LoggingStopWatch;
import org.perf4j.StopWatch;
public class Example1 {
public static void main(String[] args) throws InterruptedException{
method1();
method2();
method3();
}
/**
* 监控一处代码示?/span>
* @throws InterruptedException
*/
private static void method1() throws InterruptedException{
//创徏一个监控对象,q里使用LoggingStopWatchQ它是把l果直接输出到控制台。我们也可以
//使用StopWatch的其他子c,比如Q?/span>Log4JStopWatchQ?/span>CommonsLogStopWatch。不q这些子c需
//要工E用日志框?/span>
StopWatch stopWatch = new LoggingStopWatch("codeBlock1");
//q里是一些需要监控的代码Q我们命名ؓcodeBlock1
//使用U程休眠是ؓ了模拟代码执行时?/span>
Thread.sleep((long)(Math.random() * 1000L));
//停止计算代码性能
stopWatch.stop();
}
/**
* 一个方法多Z码监?/span>
* @throws InterruptedException
*/
private static void method2() throws InterruptedException{
StopWatch stopWatch = new LoggingStopWatch();
Thread.sleep((long)(Math.random() * 1000L));
stopWatch.lap("codeBlock3");
Thread.sleep((long)(Math.random() * 1000L));
stopWatch.lap("codeBlock4");
Thread.sleep((long)(Math.random() * 1000L));
stopWatch.lap("codeBlock5");
Thread.sleep((long)(Math.random() * 1000L));
stopWatch.stop("codeBlock6");
}
/**
* stopҎ(gu)可以加入一些说明信?/span>
*/
private static void method3(){
StopWatch stopWatch = new LoggingStopWatch();
try {
// the code block being timed - this is just a dummy example
long sleepTime = (long)(Math.random() * 1000L);
Thread.sleep(sleepTime);
if (sleepTime > 500L) {
throw new Exception("Throwing exception");
}
stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}
}
}
q行l果Q?/span>
start[1334457619937] time[355] tag[codeBlock1]
start[1334457620296] time[152] tag[codeBlock3]
start[1334457620453] time[138] tag[codeBlock4]
start[1334457620593] time[598] tag[codeBlock5]
start[1334457621187] time[700] tag[codeBlock6]
start[1334457621890] time[619] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
Perf4j主要的用途是计量代码性能和分析性能数据?/span>
Z么要使用q个工具呢?我们可以联想下最早期java开发者调试代码用的方式Q以前没有日志框Ӟ?/span>java开发就使用System.out.println()来输己想查看的变量。但是这样项目上U的话,pLq些打印语句以减性能影响。那万一在线上出问题了,调试哪里出问题就很麻烦,因ؓ没有输出的日志可查。所以后来有人开发了日志框架Q通过日志U别控制日志的输出?/span>
cM的,如果没有perf4jQ我们在查看代码q行旉的话可以用以下代码来实现Q?/span>
long start = System.currentTimeMillis();
// execute the block of code to be timed
System.out.println("ms for block n was: " + (System.currentTimeMillis() - start));
q种方式有几个缺点:
1?nbsp;q种方式输出内容比较单一Q就是代码ȝq行旉。但是我们代码需要查看的性能指标有更多,比如ȝq_|最|最大|tps{等?/span>
2?nbsp;也许我们的代码在U上q行Q我们想把这些值通过图表的Ş式展C出来。或者把q些内容通过jmx输出?/span>
3?nbsp;另外Q我们可能把perf4j?/span>log4jQ?/span>slf4j{日志框架和日志门面pȝ整合h?/span>
Z以上q些问题Q所以开源社区就出现?/span>perf4jQh多力量大Q社区的力量是强大Q?/span>
Perf4j一些特性:
l 单的停止查看机制来计语句时间消耗输出?/span>
l 命o行解?/span>log文g产生汇L据和图表?/span>
l 单的集成日志框架和门面框架?/span>
l 自定?/span>log4j?/span>logback?/span>appenders来生数据和图表?/span>
l 通过jmx查看性能指标QƈҎ(gu)阈值发送消息?/span>
l Web工程可以通过servlet来输出性能指标?/span>
l Perf4j可以?/span>aop{切面框架整合v来输出性能指标?/span>
l Perf4j是一个可扩展的架构?/span>
公司最q严抓Y件质量问题,我抽IZ解了下提高代码质量的一些开源工兗其中一个就?/span>findbugs。?/span>findbugs有很多方式,比如Q安?/span>eclipse findbugs插gQ通过maven调用生成报告。今天主要演CZmaven?/span>findbugs集成?/span>
W一步:下蝲mavenQ我使用的是maven3。把maven的命令加?/span>PATH环境变量?/span>
W二步:创徏一个普通的maven java工程。命令如下:mvn archetype:maven-archetyp-quickstart –DgroupId=com.tianya –DartifactId=baowu。如果正常执行的话会生成如下l构的一个工E?/span>
W三步:我们看下pom文g
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tianya</groupId>
<artifactId>baowu</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!--配置插g来源 -->
<pluginRepositories>
<pluginRepository>
<id>Codehaus repository</id>
<url>http://repository.codehaus.org/</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<!-- <configLocation>${basedir}/springside-findbugs.xml</configLocation> -->
<threshold>High</threshold>
<effort>Default</effort>
<findbugsXmlOutput>true</findbugsXmlOutput>
<!-- findbugs xml输出路径--> <findbugsXmlOutputDirectory>target/site</findbugsXmlOutputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
我来解释?/span>xml配置Q?/span>
l 配置插g下蝲地址
<!--配置插g来源 -->
<pluginRepositories>
<pluginRepository>
<id>Codehaus repository</id>
<url>http://repository.codehaus.org/</url>
</pluginRepository>
</pluginRepositories>
l ׃maven核心做的事情都是抽象的构E,很多实际的工作都是具体的插g来实现。所以很昄Q?/span>maven以插件的方式集成findbugs?/span>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<!-- <configLocation>${basedir}/springside-findbugs.xml</configLocation> -->
<!-- findbugs xml输出--> <findbugsXmlOutput>true</findbugsXmlOutput>
<!-- findbugs xml输出路径--> <findbugsXmlOutputDirectory>target/site</findbugsXmlOutputDirectory>
</configuration>
</plugin>
l 大家注意Cfindbugs插g里,我注释掉了一句话Q其实这句话是可以使用自己?/span>fingbugs配置来做查。我用的?/span>springside的一?/span>xml文g?/span>
W四步:配置好相x件之后,接下来就是执行相兛_令了?/span>
mvn compile findbugs:findbugs生成报告。报告生成的地址是${目根目?/span>}/target/site。也可以通过mvn findbugs:gui gui界面查看findbugs?/span>report?/span>
从学校毕业到工作已经2q半旉了,在豆瓣、当当、京东和亚玛逊上x了很多书c,也比较喜Ƣ逛书店。当然买了很多和看了部分Q自己家里很多书q没看(人类的惰性,借口Q。在q两q半旉内,C一些弯路,所以想ȝ下自q学习生?/span>
毕业的时候去了一家创业型的互联网公司Q在q家公司没有M培训机制QQ何东襉K需要靠自己来捉摸。根据工作需要看?/span>struts2Q?/span>springQ?/span>hibernateQ?/span>jstlQ?/span>jspQ?/span>servlet{一?/span>J2EE相关lg的书和资料。仅靠这些技术也能搭建出一个符合品的|站。接触到infoq|站之后Q了解了一些大型网站的架构变迁{技术,在一q的旉内不断追寻这些不W合自己目前需要的技术,充其量就是开阔了自己技术的眼界。由于互联网公司的一些劣势,D我有了蟩槽的xQ但是出去面试之后,才知道自己是井底之蛙。自׃热爱技术,也算努力学习和研I的Q自己反思和ȝ了一下:不注重基?/span>
那么学习什么才基呢?我主要列举下我的学习书单Q?/span>
ü 计算机基QQ何Y件运行的基础?/span>
ü 操作pȝQ硬件管理的软gQ我们的应用软g主要依赖于操作系l?/span>
n 鸟哥?/span>LinuxU房?/span> 基础学习?/span>
n 操作pȝ原理
ü 数据l构QY?/span>=数据l构+法。其实操作系lY件和应用软g都在大量应用数据l构?/span>
n 大话数据l构
ü |络Q系l一定需要与外部交互Q那需要网l?/span>
ü 数据库:存储数据?/span>
n MySQL 5 权威指南-(W?/span>3?/span>)
ü 软g工程Q开发Y件是一个大工程Q需要有一套理论来理软g开发?/span>
n 软g工程
ü 法Q尚未接触?/span>
ü Java基础Q具体的高语言Q最好的学习地方是java的官方网站和开源代码?/span>
n Java|络~程(中文?/span> W三?/span>)
ü Javaq阶Q面向对象思想、设计模式和J2EE深入?/span>
n 企业应用架构模式
n J2EE设计开发编E指?/span>Q?/span>Expert One-on-One J2EE Design and DevelopmentQ?/span>
n Expert One-on-One J2EE Development without EJB
学习了这些基之后Q我们在来说分布式,nosqlQ云计算Q企业集成等{。只有掌握了基础我们才能更好的创新?/span>
Java语言?/span>c语言有一个非帔R要的区别是Q内存管理方式的不同Q?/span>java语言内存理不需要程序开发h员关注,?/span>c语言的内存的h和释N是开发h员来处理。辩证的思维来看Q不同内存管理实现方式有优点和缺点,所以语a应用的场景,效率会有很大不同?/span>
Jvmq行时的数据区域主要有:E序计数器、虚拟机栈、本地方法栈、方法区和堆。其中程序计数器、虚拟机栈和本地Ҏ(gu)栈是U程独nQ而方法区和堆是所有线E共享?/span>
ü E序计数器:jvm每个U程都有一个程序计数器。在M时刻都有一个线E的Ҏ(gu)在运行,如果q个Ҏ(gu)不是本地Ҏ(gu)Q那么程序计数器存放的就是正在执行的指o地址Q如果是本地Ҏ(gu)Q那么程序计数器中存攄指定地址?/span>undefined?/span>
ü 虚拟机栈Q当jvm创徏一个线E的时候就会ؓU程分配一个虚拟机栈。主要用于存放方法的一些本地变量和部分l果Q一般这里的大小都是固定Q但不是l对。一个方法的执行到完成就是栈的入栈和出栈。假讑֜某方法中定义了一个对?/span>Object obj=new Object();其中obj是存攑֜栈上Q?/span>new Object()是在堆上分配?/span>-Xss可以控制jvm虚拟机栈的大?/span>
ü 本地Ҏ(gu)栈:大体跟虚拟机栈类|不过是给本地Ҏ(gu)使用的。虚拟机栈和本地Ҏ(gu)栈在hotspot是没有分开实现的,而是l称为栈?/span>
ü Ҏ(gu)区:主要存放静态变量,帔RQ类加蝲器加载的cȝ一些信息?/span>
ü 堆:jvml大部分的对象分配都在堆上分配?/span>-Xmn –Xmx是控制堆最值和最大|一般堆的大在使用了超q?/span>mx讑֮?/span>70%的时候,׃自动扩大到最大|所以防止这U扩大和~小我们讄成一L倹{?/span>
ClassCastExceptioncd转换异常Q是一个运行时异常?/span>
非常常见是不同cd之间的强制类型{换就会抛?/span>ClassCastException异常。还有一U就是不?/span>ClassLoader加蝲的相同的cd转换也会抛出ClassCastException。接下来我用代码来详l解释下?/span>
1?nbsp;强制cd转换
public class ClassCastExceptionTest {
/**
* @param args
*/
public static void main(String[] args) {
Animal a1 = new Dog(); //1
Animal a2 = new Cat(); //2
Dog d1 = (Dog)a1; //3
Dog d2 = (Dog)a2; //4
}
}
把猫转换成狗Q是不对的。后面注释ؓ4的代码是无法正常赋值的?/span>
Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to Dog
at ClassCastExceptionTest.main(ClassCastExceptionTest.java:13)
2?nbsp;不同classloader加蝲相同cdcM间的转换
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassCastExceptionTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
File file = new File(Thread.currentThread().getContextClassLoader().getResource("").getPath());
URL[] urls = {file.toURL()};
URLClassLoader classloader1 = new URLClassLoader(urls, ClassLoader.getSystemClassLoader().getParent());
Class classloader1Animal1 = classloader1.loadClass("Dog");
Dog dog1 = (Dog)classloader1Animal1.newInstance();
URLClassLoader classloader2 = new URLClassLoader(urls, ClassLoader.getSystemClassLoader().getParent());
Class classloader1Animal2 = classloader1.loadClass("Dog");
Dog dog2 = (Dog)classloader1Animal1.newInstance();
dog1 = dog2;
}
}
代码中我们看?/span>dog1=dog2Q这栯值是会抛异常的?/span>
Exception in thread "main" java.lang.ClassCastException: Dog cannot be cast to Dog
at ClassCastExceptionTest.main(ClassCastExceptionTest.java:17)
以后大家遇到classCastException的时候要注意了,不一定是强制cd转换D的,也有可能不同?/span>classloader加蝲了相同的c,然后q个cM同的实例q行赋倹{?/span>