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较为便利。
原因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程序设计和编码,提高JAVA性能
- Java性能优化技巧集锦
- Java 程序编码规范 编程技巧 Swing 调试
- Java 性能优化技巧集锦 (3)
- Java 性能优化技巧集锦 (2)
- Java 性能优化技巧集锦 (1)
- Java性能优化技巧集锦
- Java性能优化技巧集锦(通用篇)
- Java 性能优化技巧集锦 (1)
- Java性能优化技巧集锦
- Java 性能优化技巧集锦 (4)
- Java 性能优化技巧集锦
- Java性能优化技巧(二)
- Java 性能优化技巧
- Java 性能优化技巧集锦 (2)
- Java 界面设计技巧【原创】
- Java性能优化技巧集锦(转贴)
- [转载] Java 性能优化技巧集锦(2)
- Java 性能优化技巧集锦 (5)
- Java 性能优化技巧集锦 (6)