java 编译优化问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 编译优化问题相关的知识,希望对你有一定的参考价值。

java 编译时可以采取的优化措施?

用eclipse galileo编译如下代码,
package test;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.out;

public class TimeStep_100ms
public static void main(String[] args)
// TODO Auto-generated method stub
long start = currentTimeMillis();
for (int i = 0; i < 99999; i++)
for (int j = 0; j < 9999; j++)
;
out.println(currentTimeMillis() - start);



运行了一下,发现它在执行空循环,以为是eclipse用的compiler 不好,用sun的jdk编译后执行,发现运行时间还是那样,它也没做循环优化。

问问高手,能做到最好的优化的java 编译器是哪个,openJDK怎么样?
或者我应该加点什么参数让javac做更多优化?
看来优化是在运行时用hotspot做的,那我运行时是否应该加点什么参数来提高速度?比如 -server或垃圾回收配置之类的参数?

java编译的结果是字节码而不是二进制,所以在运行时vm的优化才是重要的,包括VM的回收策略、分配给VM内存的大小都能在一定程度上影响性能。Sun的VM支持热点编译,对高频执行的代码段翻译的2进制会进行缓存,这也是VM的一种优化。

IBM JVM处理数学运算速度最快,BEA JVM处理大量线程和网络socket性能最好,而Sun JVM处理通常的商业逻辑性能最好。不过Hotspot的Server mode被报告有稳定性的问题。

Java 的最大优势不是体现在执行速度上,所以对Compiler的要求并不如c++那样高,代码级的优化还需要程序员本身的功底。

贴个java的运行参数:

Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)

where options include:
-client to select the "client" VM
-server to select the "server" VM
-hotspot is a synonym for the "client" VM [deprecated]
The default VM is client.

-cp <class search path of directories and zip/jar files>
-classpath <class search path of directories and zip/jar files>
A ; separated list of directories, JAR archives,
and ZIP archives to search for class files.
-D<name>=<value>
set a system property
-verbose[:class|gc|jni]
enable verbose output
-version print product version and exit
-version:<value>
require the specified version to run
-showversion print product version and continue
-jre-restrict-search | -jre-no-restrict-search
include/exclude user private JREs in the version search
-? -help print this help message
-X print help on non-standard options
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
enable assertions
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
disable assertions
-esa | -enablesystemassertions
enable system assertions
-dsa | -disablesystemassertions
disable system assertions
-agentlib:<libname>[=<options>]
load native agent library <libname>, e.g. -agentlib:hprof
see also, -agentlib:jdwp=help and -agentlib:hprof=help
-agentpath:<pathname>[=<options>]
load native agent library by full pathname
-javaagent:<jarpath>[=<options>]
load Java programming language agent, see

java.lang.instrument

-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see

documentation)
-Xcheck:jni perform additional checks for JNI functions
-Xshare:off do not attempt to use shared class data
-Xshare:auto use shared class data if possible (default)
-Xshare:on require using shared class data, otherwise fail.

Java虚拟机(JVM)参数配置说明

在Java、J2EE大型应用中,JVM非标准参数的配置直接关系到整个系统的性能。
JVM非标准参数指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需

要任何配置。但是在生产环境中,为了提高性能,往往需要调整这些参数,以求系统达

到最佳新能。
另外这些参数的配置也是影响系统稳定性的一个重要因素,相信大多数Java开发人员都

见过“OutOfMemory”类型的错误。呵呵,这其中很可能就是JVM参数配置不当或者就没

有配置没意识到配置引起的。

为了说明这些参数,还需要说说JDK中的命令行工具一些知识做铺垫。

首先看如何获取这些命令配置信息说明:
假设你是windows平台,你安装了J2SDK,那么现在你从cmd控制台窗口进入J2SDK安装目

录下的bin目录,然后运行java命令,出现如下结果,这些就是包括java.exe工具的和

JVM的所有命令都在里面。

-----------------------------------------------------------------------
D:\j2sdk15\bin>java
Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)

where options include:
-client to select the "client" VM
-server to select the "server" VM
-hotspot is a synonym for the "client" VM [deprecated]
The default VM is client.

-cp <class search path of directories and zip/jar files>
-classpath <class search path of directories and zip/jar files>
A ; separated list of directories, JAR archives,
and ZIP archives to search for class files.
-D<name>=<value>
set a system property
-verbose[:class|gc|jni]
enable verbose output
-version print product version and exit
-version:<value>
require the specified version to run
-showversion print product version and continue
-jre-restrict-search | -jre-no-restrict-search
include/exclude user private JREs in the version search
-? -help print this help message
-X print help on non-standard options
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
enable assertions
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
disable assertions
-esa | -enablesystemassertions
enable system assertions
-dsa | -disablesystemassertions
disable system assertions
-agentlib:<libname>[=<options>]
load native agent library <libname>, e.g. -agentlib:hprof
see also, -agentlib:jdwp=help and -agentlib:hprof=help
-agentpath:<pathname>[=<options>]
load native agent library by full pathname
-javaagent:<jarpath>[=<options>]
load Java programming language agent, see

java.lang.instrument
-----------------------------------------------------------------------
在控制台输出信息中,有个-X(注意是大写)的命令,这个正是查看JVM配置参数的命

令。

其次,用java -X 命令查看JVM的配置说明:
运行后如下结果,这些就是配置JVM参数的秘密武器,这些信息都是英文的,为了方便

阅读,我根据自己的理解翻译成中文了(不准确的地方还请各位博友斧正)
-----------------------------------------------------------------------
D:\j2sdk15\bin>java -X
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see

documentation)
-Xcheck:jni perform additional checks for JNI functions
-Xshare:off do not attempt to use shared class data
-Xshare:auto use shared class data if possible (default)
-Xshare:on require using shared class data, otherwise fail.

The -X options are non-standard and subject to change without notice.
-----------------------------------------------------------------------

JVM配置参数中文说明:
-----------------------------------------------------------------------
1、-Xmixed mixed mode execution (default)
混合模式执行

2、-Xint interpreted mode execution only
解释模式执行

3、-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
设置zip/jar资源或者类(.class文件)存放目录路径

3、-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
追加zip/jar资源或者类(.class文件)存放目录路径

4、-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
预先加载zip/jar资源或者类(.class文件)存放目录路径

5、-Xnoclassgc disable class garbage collection
关闭类垃圾回收功能

6、-Xincgc enable incremental garbage collection
开启类的垃圾回收功能

7、-Xloggc:<file> log GC status to a file with time stamps
记录垃圾回日志到一个文件。

8、-Xbatch disable background compilation
关闭后台编译

9、-Xms<size> set initial Java heap size
设置JVM初始化堆内存大小

10、-Xmx<size> set maximum Java heap size
设置JVM最大的堆内存大小

11、-Xss<size> set java thread stack size
设置JVM栈内存大小

12、-Xprof output cpu profiling data
输入CPU概要表数据

13、-Xfuture enable strictest checks, anticipating future default
执行严格的代码检查,预测可能出现的情况

14、-Xrs reduce use of OS signals by Java/VM (see

documentation)
通过JVM还原操作系统信号

15、-Xcheck:jni perform additional checks for JNI functions
对JNI函数执行检查

16、-Xshare:off do not attempt to use shared class data
尽可能不去使用共享类的数据

17、-Xshare:auto use shared class data if possible (default)
尽可能的使用共享类的数据

18、-Xshare:on require using shared class data, otherwise fail.
尽可能的使用共享类的数据,否则运行失败

The -X options are non-standard and subject to change without notice.
参考技术A eclipse本身是没有编译器的,就是你环境变量设置的jdk,MyEclipse自带的jdk也是sun的

空循环还是应该执行的,如果我想用空循环来达到某种目的,结果你给我弄掉了,这不。。。有些优化是仁者见仁,智者见智的事情,vs那样做未必好
参考技术B for (int i = 0; i < 99999; i++)
for (int j = 0; j < 9999; j++)
a=1;
这样不就可以不会优化掉了呀,
参考技术C java没有自动优化的功能,至于编译器,只有jdk带的那个javac。eclipse自带了jre的javac,和jdk里面的javac是一样的玩意,哪来的好不好?

比方做多线程的时候,有时候需要让一个线程等待下,就可以使用空循环,那你怎么优化?

优化要靠你自己平时的积累
参考技术D 编译器只负责编译和运行没啥关系。你这个问题纯属你自己造成的。不管那个平台编译出来的结果都是一样的,这个是跨平台的基础,要是编译出来的东西都不一样,那还怎么跨平台啊。编译器只负责检查语法错误,而运行的速度和你的硬件以及代码结构有关系。
从你这段代码看你是想测试代码运行时间,你中间加了一段没意义的空代码,最直接的提速就是删除空代码。你让人家白忙活还怪人家速度慢,这个慢是你自己造成的。

你要提高代码运行速度,有一个原则 大事化小 小事化了 不要在把一件很长的事情放到一段代码,不要做没意义的事情。不要把提高效率寄托在垃圾回收上,最好的代码是尽可能少的触发垃圾回收。特别是不要手动调用垃圾回收。

并发编程-Java内存模型:解决可见性与有序性问题

背景

我们知道导致cpu缓存导致了可见性问题,编译器优化带来了有序性问题。那么如果我们禁用了cpu缓存与编译器优化,就能够解决问题,但是性能就无法提升了。所以一个合理的方案,就是按照一定规范来禁用缓存和编译器优化,即在某些情况下禁用缓存与编译器优化。Java内存模型就是这样的一个规范,用来解决可见性与有序性问题

概念

java内存模型本质上就是规范了JVM如何按照规则禁用缓存和编译器优化,既面向应用开发人员,也面向jvm的实现。这些规范包括了volatile、synchronized和final三个关键字,以及六项Happens-Before规则。

volatile

volatile实质就是告诉编译器,对volatile修饰的变量,不能使用cpu缓存,必须从内存中读取或者写入。

Happens-Before规则,简称为HB

HB本质是一种可见性,即前面一个操作结果对后面的操作是可见的,换句话说就是后面的操作能够看见前面的操作结果。HB约束了编译器的优化行为,允许优化,但是优化后的结果要符合HB规则

同一线程顺序性规则

这条规则是指在一个线程中,按照程序顺序,前面的操作HB于后续的操作。

volatile变量规则

这条规则是指对一个 volatile 变量的写操作, HB于后续对这个变量的读操作。

传递性

这条规则是指A HB于 B,B HB于 C,那么A HB 于C。
根据以上三条格则继续看下面的例子

public class HappensBeforeDemo 
    int x = 0;
    volatile boolean v = false;
    public void write()
        x = 42;
        v = true;
    
    public void read()
        if(v)
            //x为多少呢
        
    

当线程A执行完write方法,线程B执行read方法后,读到了v为true后,x是多少呢?首先在线程A中,根据同一线程顺序性规则,x=42 HB与v=true;再根据volatile变量规则,v=true的写操作HB于v的读操作;再根据传递性规则,x=42 HB于v的读操作,所以线程B中的值一定为42。在java并发包中的工具类,正是依靠这三条规则来实现可见性的

synchronized锁规则

这条规则指对一个锁的解锁操作HB于后续对这个锁的加锁加锁操作

线程start()规则

主线程A启动子线程B后,子线程B能够看到主线程在启动子线程之前的操作结果

线程join规则

在主线程A中等待子线程B完成(主线程A通过调用子线程B的join方法实现),当子线程完成后(主线程中的join方法返回),主线程能够看到子线程的操作结果

以上是关于java 编译优化问题的主要内容,如果未能解决你的问题,请参考以下文章

程序编译与代码优化 -- 早期(编译期)优化

Java技术指南「编译器专题」重塑认识Java编译器的执行过程(常量优化机制)!

java编译优化

Java技术专题「编译器专题」重塑认识Java编译器的执行过程(常量优化机制)

15个问题自查你真的了解java编译优化吗?

执行引擎:程序编译与代码优化