jvm运行完程序后将程序放jvm在哪里里

一段小程序有几种写法,如何评价JVM对其的执行效率 - 高级语言虚拟机 - ITeye群组
起因是碰巧需要写段小程序,需要检测int x+int y、int x-int y、int x*int y是否会出现overflow或underflow。其实原理蛮简单的,但是需要兼顾一些效率。我调研了一些材料,发现有几种代码的写法:① int r = x + 然后利用位运算符判断:if (((x ^ r) & (y ^ r)) & 0) ……② long r = (long) x + 然后判断:r == (int) r ……③ 跟①思路一致,但是位运算的写法是: if (((x & y & ~r) | (~x & ~y & r)) & 0) ……采用①方式的比如Java8的Math. addExact()
采用②方式的比如Google Guava的IntMath . checkedAdd () 采用③方式的是StackOverflow的一个回答 那么问题来了:[Q1] 如何定性分析这三种写法的效率?简单的想,可以分析生成的bytecode分别有几条指令,每条逻辑执行时间是多少,但是考虑到实际执行时JIT出来的指令及序列会不一样,导致简单分析的结果不对;[Q2] 如何定量测试这三种写法的效率?就算我们写了测试的code来循环很多次,得到每次平均运行时间,但是实际使用的环境中,如果把这段检测overflow/underflow的代码放到方法里被调用,是不是方法调用开销的本身就比这三段写法的性能差异大多了?再比如在笔记本本地的Windows环境下测试,三者的效率有个相对高低,是否会与服务器Linux环境下实际跑时的相对高低一致呢?可能问题有些simple & naive, 但还是想看到各位的解答和探讨,谢谢各位~
我只是想说在Java层面讨论这种粒度的细节可能不太合适。
Oracle JDK8 / OpenJDK8里的HotSpot VM里,当被HotSpot Server Compiler(C2)编译过后,Math.addExact()的overflow检查是用硬件自带的指令完成的,开销极低,比各种显式用运算的方式检查都快多了。
例如在x86上,Math.addExact(int, int)int会被编译为类似:
add eax, edx
# 普通的32位整数加法
jo throw_ArithmeticException # overflow的话跳到抛异常的逻辑
...
因为x86上加法指令都会设置EFLAGS/RFLAGS里的OF(overflow flag),要检测有没有overflow只要在后面用jo(jump if overflow)就好了。其它CPU也是类似,很少CPU是没有这种功能的…
这么一来,在没有overflow的时候无论写什么形式的Java代码都不如直接调用Math.addExact()快;在有overflow的时候则不同,因为Java 8 API的设计还是太煞笔,只提供了抛异常的版本而没提供别的方式返回是否overflow的版本的API,所以如果经常overflow的话用Math.addExact()未必快,要看情况。
(败就败在Java还是没有out参数也不允许返回多值…)
感谢@RednaxelaFX 大大的回复!
R大,你说的硬件指令检测overflow开销极低、overflow之后用低效的Exception来报错所以效率不高这两点解释的很明白,赞
不过下面这点还是很明白,进一步请教下R大:
RednaxelaFX 写道Oracle JDK8 / OpenJDK8里的HotSpot VM里,当被HotSpot Server Compiler(C2)编译过后,Math.addExact()的overflow检查是用硬件自带的指令完成的
既然Oracle JDK 8/Open JDK 8里的java代码和bytecode都是用的显示运算检查overflow,那基于什么判断HotSpot执行时会编译为类似jo指令而去掉显式的Java位运算呢?比如是基于类名、方法名判断,只针对java.lang.Math做这样的编译,还是基于对bytecode的语义分析知道这段代码其实语义上等同于jo指令所以替换掉呢?
现在在HotSpot VM里实现的版本是把java.lang.Math.addExact()当作特殊方法,然后整个方法直接用特殊方式实现,绕开原本在里面的字节码。这种做法叫做“intrinsic”。
具体的实现的最初版在这里:
我以前在GreenTeaJUG的活动上介绍过HotSpot的intrinsics:
活动帖:
演示稿:
(本来也上传过到新浪微盘,但它被变成了“正在审核”…真纱布)
===================================
我以前实现过的一个原型则是在C2里模式匹配Math.addExact()里的写法,只要用了那种形式的异或来检查溢出,我的代码就会把它匹配上然后把它跟前面的运算关联起来,最后在生成代码的时候生成出jo。这种匹配方式应用范围会更广,但是匹配会比较麻烦而且不太好维护,所以后来没有实际用在产品里。
RednaxelaFX 写道
我以前在GreenTeaJUG的活动上介绍过HotSpot的intrinsics:活动帖:演示稿:(本来也上传过到新浪微盘,但它被变成了“正在审核”…真纱布)
RednaxelaFX 写道
我以前实现过的一个原型则是在C2里模式匹配Math.addExact()里的写法……
学习了一遍你的&Intrinsic Methods in HotSpot VM&,收获很多,大赞 并且在演示稿里找到了Math.addExact(),竟然是“撞到枪口”了 :
ps. Azul付你钱让你在这回复问题的嘛?
抱歉一个intrinsic把您最初的几个问题全部绕开了。那些也是有趣的问题,值得讨论讨论。
Now7! 写道ps. Azul付你钱让你在这回复问题的嘛?
哈哈怎么可能。纯兴趣回复。所以也没办法做到所有帖都回复(抱歉
要付我工资在论坛回复问题那估计也得是在上了。
况且这个HLLVM群组主要讨论的HotSpot VM都是Oracle版的而不是Azul版的,要给我工资也应该是老东家给(逃
=========================
话说 -XX:+UseMathExactIntrinsics 应该是在JDK8u25才默认开启的,在那之前的JDK8要用intrinsic版的Math.xxxExact的话得要 -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics 才行(当然是因为当时还有bug…)
想测试一下loop unroll对性能的影响,有什么办法可以关掉自动unrolling吗?
tiancongyun 写道想测试一下loop unroll对性能的影响,有什么办法可以关掉自动unrolling吗?
要关掉C2的loop unrolling试试 -XX:LoopUnrollLimit=0您所在的位置: &
用JavaScript编写JVM可成功运行Java程序
用JavaScript编写JVM可成功运行Java程序
开源中国社区
日,超级大牛程序员Artur Ventura老外发布新闻说已经成功用JavaScript编写Java虚拟机JVM,并可以以运行Java程序。
TechFrom科技源 11.21日,现在,Java语言技术开发人员占据了程序员的大半江山,刚刚老外发布新闻说已经成功用JavaScript编写Java虚拟机JVM,并可以以运行Java程序,via。程序员Artur Ventura,这位超级大牛,用JavaScript 写了一个java 虚拟机 BicaVM,虚拟机代码可以通过Github 获得,点击进入BicaVM。如果你想看看这位技术大牛的个人博客可以点击进入,Surf the Edge (Artur Ventura的个人博客)
另外,经过了 6个月的奋战,BicaVM ,一个用 JavaScript 语言写的 Java 虚拟机基本告一段落,可以运行 60%以上的 Java 虚拟机编译代码,但是还没有经过优化。
因为 javascript 是跨浏览器运行,所以BicaVM 虚拟机完全可以在 iPad 和 iPhone 等移动设备上运行使用。
更多JavaScript编写Java虚拟机JVM成功英文信息可以点击进入看技术人员个人博客,如上地址。
原文链接:http://www.oschina.net/news/23368/bicavm
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&&&的更多文章
本专题关注Java技术的发展动态,希望能给你一些Java学习中的重点
网友评论TOP5
诞生于1991年的Java如今已经成为世界范围内应用最为广泛的编程语言之一,专题中...
日,微软TechED 2011在北京万事达中心召
HTML5仿佛一夜间受到大多业内巨头的青睐,有点像《海
当年,雅虎的信息中枢曾经是互联网用户的第一入口,Go
osCommerce是一款免费的、开放源代码的专业电子商务解决方案。本书以通俗易懂的语言向读者展示了该软件强大的功能和简易的操作方
51CTO旗下网站当前位置:
(2 次投票, 评分: 5.00, 总分: 5)
&Loading ...
Tomcat 的启动参数位于tomcat的安装目录\bin目录下,如果你是Linux操作系统就是catalina.sh文件,如果你是Windows操作系统那么你需要改动的就是catalina.bat文件。打开该文件,一般该文件头部是一堆的由##包裹着的注释文字,找到注释文字的最后一段如:
# $Id: catalina.sh 522797 2007-03-27 07:10:29Z fhanik $
# -----------------------------------------------------------------------------
# OS specific support.
$var _must_ be set to either true or false.
敲入一个回车,加入如下的参数
Linux系统中tomcat的启动参数
export JAVA_OPTS=&-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m
-XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true &
Windows系统中tomcat的启动参数
set JAVA_OPTS=-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m
-XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true
上面参数好多啊,可能有人写到现在都没见一个tomcat的启动命令里加了这么多参数,当然,这些参数只是我机器上的,不一定适合你,尤其是参数后的value(值)是需要根据你自己的实际情况来设置的。
参数解释:
我不管你什么理由,只要你的tomcat是运行在生产环境中的,这个参数必须给我加上
因为tomcat默认是以一种叫java –client的模式来运行的,server即意味着你的tomcat是以真实的production的模式在运行的,这也就意味着你的tomcat以server模式运行时将拥有:更大、更高的并发处理能力,更快更强捷的JVM垃圾回收机制,可以获得更多的负载与吞吐量.
即JVM内存设置了,把Xms与Xmx两个值设成一样是最优的做法,有人说Xms为最小值,Xmx为最大值不是挺好的,这样设置还比较人性化,科学化。人性?科学?你个头啊。
大家想一下这样的场景:
一个系统随着并发数越来越高,它的内存使用情况逐步上升,上升到最高点不能上升了,开始回落,你们不要认为这个回落就是好事情,由其是大起大落,在内存回落时它付出的代价是CPU高速开始运转进行垃圾回收,此时严重的甚至会造成你的系统出现“卡壳”就是你在好好的操作,突然网页像死在那边一样几秒甚至十几秒时间,因为JVM正在进行垃圾回收。
因此一开始我们就把这两个设成一样,使得Tomcat在启动时就为最大化参数充分利用系统的效率,这个道理和jdbcconnection pool里的minpool size与maxpool size的需要设成一个数量是一样的原理。
–Xmn:年轻代大小(1.4or lator)
设置年轻代大小为512m。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约需要占用多少内存,可能会有多少线程同时运行等。一般不易设置超过1M,要不然容易出现out ofmemory。
-XX:+AggressiveOpts
作用如其名(aggressive),启用这个参数,则每当JDK版本升级时,你的JVM都会使用最新加入的优化技术(如果有的话)
-XX:+UseBiasedLocking
启用一个优化了的线程锁,我们知道在我们的appserver,每个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。
-XX:PermSize=128M-XX:MaxPermSize=256M
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
在数据量的很大的文件导出时,一定要把这两个值设置上,否则会出现内存溢出的错误。
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
那么,如果是物理内存4GB,那么64分之一就是64MB,这就是PermSize默认值,也就是永生代内存初始大小;
四分之一是1024MB,这就是MaxPermSize默认大小。
-XX:+DisableExplicitGC
在程序代码中不允许有显示的调用”System.gc()”。看到过有两个极品工程中每次在DAO操作结束时手动调用System.gc()一下,觉得这样做好像能够解决它们的out ofmemory问题一样,付出的代价就是系统响应时间严重降低,就和我在关于Xms,Xmx里的解释的原理一样,这样去调用GC导致系统的JVM大起大落,性能不到什么地方去哟!
-XX:+UseParNewGC
对年轻代采用多线程并行回收,这样收得快。
-XX:+UseConcMarkSweepGC
即CMS gc,这一特性只有jdk1.5即后续版本才具有的功能,它使用的是gc估算触发和heap占用触发。
我们知道频频繁的GC会造面JVM的大起大落从而影响到系统的效率,因此使用了CMS GC后可以在GC次数增多的情况下,每次GC的响应时间却很短,比如说使用了CMS GC后经过jprofiler的观察,GC被触发次数非常多,而每次GC耗时仅为几毫秒。
-XX:MaxTenuringThreshold
设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。
这个值的设置是根据本地的jprofiler监控后得到的一个理想的值,不能一概而论原搬照抄。
-XX:+CMSParallelRemarkEnabled
在使用UseParNewGC 的情况下, 尽量减少 mark 的时间
-XX:+UseCMSCompactAtFullCollection
在使用concurrent gc 的情况下, 防止 memoryfragmention, 对live object 进行整理, 使 memory 碎片减少。
-XX:LargePageSizeInBytes
指定 Java heap的分页页面大小
-XX:+UseFastAccessorMethods
get,set 方法转成本地代码
-XX:+UseCMSInitiatingOccupancyOnly
指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 启动收集
-XX:CMSInitiatingOccupancyFraction=70
CMSInitiatingOccupancyFraction,这个参数设置有很大技巧,基本上满足(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotion failed。在我的应用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS),这时还 剩10%的空间是8兆,所以即使Xmn(也就是年轻代共512兆)里所有对象都搬到年老代里,548兆的空间也足够了,所以只要满 足上面的公式,就不会出现垃圾回收时的promotion failed;
因此这个参数的设置必须与Xmn关联在一起。
-Djava.awt.headless=true
这个参数一般我们都是放在最后使用的,这全参数的作用是这样的,有时我们会在我们的J2EE工程中使用一些图表工具如:jfreechart,用于在web网页输出GIF/JPG等流,在winodws环境下,一般我们的app server在输出图形时不会碰到什么问题,但是在linux/unix环境下经常会碰到一个exception导致你在winodws开发环境下图片显示的好好可是在linux/unix下却显示不出来,因此加上这个参数以免避这样的情况出现。
上述这样的配置,基本上可以达到:
系统响应时间增快
JVM回收速度增快同时又不影响系统的响应率
JVM内存最大化利用
线程阻塞情况最小化
本文固定链接:
【上一篇】【下一篇】
您可能还会对这些文章感兴趣!
本月热门文章使用R的程序包提示我们无法使用怎么回事?因为计算机丢失jvm.dll(解决方法)
R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。可是当我们在使用R的程序包是,又是会提示我们的无法使用,这是怎么回事?其实是因为计算机丢失jvm.dll,下面就为大家解决解决方法
R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。目前数据挖掘领域里面R是比较流行的统计软件,因为其免费的特性赢得了广大用户的喜爱。。可是当我们在使用R的程序包是,又是会提示我们的无法使用,这是怎么回事?其实是因为计算机丢失jvm.dll,遇到这种情况很简单,我们只需要修改一下环境变量即可。下面就为大家解决解决方法,希望能帮到大家!
解决方法:
打开你的java安装目录下的jre目录,在jre目录里面有一个\bin\server,将这个目录路径复制一份。例如:D:\Program Files\Java\jdk1.8.0_05\jre\bin\server
右击计算机&&属性&&高级系统设置,然后选择高级&&环境变量。
在环境变量的设置面板中找到path变量,在变量值中将刚刚复制的路径粘贴进去即可。
如果你的用户变量中也有这个path,那么也需要将其加入,没有就算了。
找到配置java环境变量是新建的classpath,把这个也添加到其中,别忘了值与值之间加分号。
最后一步,重新启动R软件,输入library(rJava) &这是你就会发现可以正常运行了,在次运行你的程序包,一切OK了。
注意事项:我这里使用的64位R软件,相应的应该使用64位java。建议使用32位的
以上就是使用R的程序包提示我们无法使用的解决方法,感谢百度经验作者CIo_qiang,希望这篇教程对大家有所帮助!请问,是不是必须装JVM才能运行JAVA应用程序(在线等解)_百度知道
请问,是不是必须装JVM才能运行JAVA应用程序(在线等解)
提问者采纳
是的,java所有程序 必须在JVM中运行。你可以装jre 就是 java的运行环境,不需要装jdk,jdk是开发程序包。
提问者评价
其他类似问题
为您推荐:
其他1条回答
必须要JRE..JRE(Java Runtime Environment,Java运行环境),运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。
java应用程序的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 jvm在哪里 的文章

 

随机推荐