您的位置:首页 > 编程语言 > Java开发

Java性能 优缺点 和 编码技巧 ——不一定始终对,VM的设计是关键。

2016-10-07 11:22 330 查看
java的GUI程序基本上是性能不要太差,虚拟机太大太慢。
服务器端,java较为便利。

原因1:虚拟机一直在执行,那么避免重复启动关闭浪费时间。启动一次就好了。
原因2:服务器内存足够大,这个java的内存回收就不会频繁的GC。

java本的性能问题

数据越界检查

java执行里,每次任何涉及数组时候,必须访问时候数组都要检查越界情况,然后妥善处理越界问题,用异常来处理。也就是循环遍历10次数组,那就检查10次越界,不越界再执行查询啥的其他操作。然而这些操作中的大部分是冗余的,很浪费时间。C和C++不检查越界直接去执行。但是越界那就程序容易奔溃。安全性和可靠性和性能的博弈。
【引申】

我在知网找到了一种 算法来减少java数组越界检查的办法。
《小型微型计算机系统》
2010年11期 ABCE:Java冗余数组越界检查消除》
  
黄锃  杨克峤  周曦
 杨珉
http://www.cnki.com.cn/Article/CJFDTotal-XXWX201011004.htm

阻塞网络I/O

java里的所有read命令都是阻塞的,也就是说。如果整个程序还未被挂起。那么这些read命令就必须存在一个独立的线程中。等待输入。
现在JDK有了lang.NIO包了

字节码转换:

字节码转换为机器码。很慢的。但是VM一般是C写的和平台相关优化之后VM还是很快的。

字节码验证:

下载的类必须字节码检查。防止恶意的代码。

类的加载:也很费劲
垃圾收集GC

GC是异步执行的。程序员并不能通过system.gc()保证执行GC。而是它自己在后台进程执行。
万一出现程序运行内存不够,GC启动,那么会出现单线程延迟,程序就停下来了。因为GC一般是单线程的,当然也有多线程的GC能够很快的回收内存。

间接寻址:

找到一个对象,先要找到引用。所以要坚持同步锁定。是不是可以查找访问。。。还有一些锁定也浪费时间。类加载锁定。创建销毁锁定。

unicode长度:

unicode是ascii的长度的二倍。这对内存来说是浪费。当然也是博弈。存的字符种类多

OO:

一个类加载到VM里面时候一定会把他的父类也加载进去。甚至该类初始化的对象涉及到的相关其他类。比如你的这个类的成员是一个其他类实例对象。当然在服务器端足够内存。

基于堆栈:

局部变量都在栈里,而不是CPU寄存器。那么访问内存比寄存器要慢啊

同步:

并发加锁保证数据一致性。那么同步等待费时间

线程:

线程容易死锁
程序编写困难
线程个数的效率函数不是线性的。也就是10个线程那么很高效。20个的时候会为线程调度反而变差。多少线程合适这是个问题

【编码技巧】

使用好算法

程序算法优化是最高效的。注重算法的高效。

继承链短一些

子类创建就要超类也在。一层层上去。那就是可烦可烦了。
当然任何一个类都继承java.lang类。

多用局部变量也就是多用栈内存,少用堆内存

栈不需要你管,堆里GC很麻烦
那么方法里的局部变量 参数都OK,静态变量,成员变量都在堆里

创建对象越少越好
多使用现成的java库

用现成的函数而不是你写的要快

n+=4 比 n=n+4快。i++比 i=i+1快
访问速度:

局部变量》static 类变量》数组访问》

使用多线程
notify和NotifyALL:

不同人不同看法,有的人认为notify性能好啊。但是可惜随机的,所以notifyALL更好,大家所有线程一起竞争。

减少string

string是不可修改的。很费堆内存。
stringbuffer更好

使用最新的编译器

比如编译器优化——非变量代码移除循环,不需要每次重新计算赋值
更适合的编译器

虚拟机

用更好的更适合的虚拟机。
-Xmsn 和 -Xmxn

设置初始化堆的大小,和最大堆的大小

使得Eden内存够大

如果你的临时对象很多,那就加大eden区域。GC喜欢收拾这些Eden的,高效的很。建议多用这些短寿命的对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 编码 性能 设计