JVM最多可创建多少线程

JVM最多可创建多少线程,第1张

这个问题比较复杂,不同环境不一样,建议精确值要实际压力测试一下。理论上是这样的:
JVM中可以生成的最大数量由JVM的堆内存大小、Thread的Stack内存大小、系统最大可创建的线程数量(Java线程的实现是基于底层系统的线程机制来实现的,Windows下_beginthreadex,Linux下pthread_create)三个方面影响。具体数量可以根据Java进程可以访问的最大内存(32位系统上一般2G)、堆内存、Thread的Stack内存来估算。
绝对理论上的最大线程数是进程的用户地址空间除以线程栈的大小(现实中,如果内存全部给线程栈使用,就不会有能运行的程序了)。因此,以32位Windows系统为例,每一个进程的用户地址空间是2G,假如每个线程栈的大小是128K,最多会有16384(=210241024 / 128)个线程。实际在32位XP系统上,大约能启动13000个线程。

随着DEC(Digital Equipment Corp)公司Alpha处理器在 年末的发布 就意味着这个世界开始进入 位计算的时代 紧接着 全球几大主要计算机公司 如IBM Hewlett Packard(惠普) Fujitsu(富士通) Sun Microsystems 也发布了各自相应的产品进入到 位 这个市场 在 年 Fujitsu旗下的HAL Computer发布了业界第一台基于 位SPARC CPU的工作站 SPARC 此后不久 Sun发布了大众期盼已久的Ultra Ultra 工作站 其内置了Sun的 位UltraSPARC处理器 时间转换到 年 IBM发布了其第一个 位PowerPC RISC芯片 RS 在 年 IBM对RS 进行改良 使其支持SMP 这就是Power 如今看起来 对 位计算来说 其整整花了五年的时间 才在 年开始大量进入市场 在本文中 将主要涉及两个现在广泛应用的 位平台 AMD 与PowerPC 并分别使用IBM与Sun Microsystems这两个Java语言巨头提供的Java虚拟机(JVM) 通过SPECjvm 与SPECjbb 的测试 来评价 位与 位中JVM的性能 (注 SPECjvm 与SPECjbb 来自Standard Performance Evaluation Corp )AMD 是Advanced Micro Devices(AMD)公司的 位平台 其扩展了工业标准的x 指令集架构 并设计在不降低任何性能的前提下 于 位模式中完全兼容现有的x 应用程序与 *** 作系统 在 年 月 AMD发布了Opteron 遵循AMD 架构的第一款处理器 与其同时 年 IBM发布了PowerPC 其是源自IBM Power 双核CPU的单核处理器 从此 IBM把 位PowerPC架构带到了桌面系统与低端服务器领域 另外要说明一点 PowerPC 也像Power 一样 可在不降低性能的前提下 本地执行 位指令 不久之后 在 年 月 由Apple Computer公司设计 基于PowerPC CPU的Power Mac G 电脑上市 Java背景介绍 在第一款 位处理器诞生不久 Java技术也出世了 并由此改写历史 Java是一种健壮的 通用的 面向对象的 构架中立的 可移植的 安全的 多线程的编程语言 并带有隐式内存管理功能 Java面向对象的特性在很大程度上与C++相似 但加入了更多的接口与扩展以创建更具灵活性的解决方案 与C++不同的是 Java不支持 *** 作符重载 多重继承和自动类型强制 Java通过广泛的运行时检查和内置的例外处理机制 达到健壮性的目的 编译器所生成的只是字节码指令 其是独立于任何特定平台的 这样就保证了架构中立性 可移植性是通过指定基本数据类型大小和其算术 *** 作符的行为来达到的 例如 int总表示一个有符号的 位整数 而float总表示一个 位的IEEE 浮点数 Java同时也有一系列的同步原语 其基于广泛使用的条件变量范式 自动内存垃圾回收(GC)简化了Java编程的难度 并极大地降低了bug的数目 但也使运行机制稍微复杂了点 在 年 也就是DEC公司发布第一款 位处理器的前一年 Sun Microsystems开始了一个名为 the Green Project 的计划 目的是要抢占 下一波计算 的先机 并为此提前做好准备 计划得出的最初结论是 移动数字设备与计算机的融合将会很快出现 在 年的夏天 计划小组演示了 (星 ) 一个通过动画式触摸屏控制的交互性手持娱乐设备 通过使用Oak 一种全新的编程语言 这个设备可控制很多不同的平台 而由James Gosling开发的Oak 其最主要的特点在于它是一个彻底独立于处理器的语言 在往后的几年中 这种语言被用于Internet 之后成为大众所知的Java 而 Oak 这个名字则因为版权问题从此消失了 在 年 月 Sun正式宣布Java的诞生 这是一种程序员只需编写一次 但却可在多种 *** 作系统及多种硬件平台上运行的语言 编写一次 随处运行 在 年 Sun发布了Java开发工具包(JDK ) 其后不久 个主要的 *** 作系统开发商宣布支持Java技术 当中也包括Microsoft 其以每年大约 万美元取得五年时间的Java许可协议 在 年 月 Sun发布了Java平台的第一个即时(JIT)编译器 在 年 月 JDK 面世 在随后的三周时间里 达到了 万次的下载量 到了 年初 这个数字达到两百万 在 年末 Java 平台发布了 大概半年后 也就是 年年中 Sun发布了三个版本的Java平台 J ME(Java Micro Edition) 应用于移动 无线及有限资源的环境 J SE(Java Standard Edition) 应用于桌面环境 J EE(Java Enterprise Edition) 应用于基于Java的应用服务器 此后 广泛应用的Java技术出现了一些framework 如Enterprise JavaBeans (EJB)和JavaServer Pages (JSP) Java技术的随后一次升级 是出现在 年 月的J SE 几周后 其获得了Apple公司Mac OS X的工业标准的支持 J SE 发布于 年 月份 对Java平台来说 这是一个几乎全新的产品 与J SE 相比 其多了近 %的类和接口 在这些新特性当中 还提供了广泛的XML支持 安全套接字支持(通过SSL与TLS协议) 全新的I/O API 正则表达式 日志与断言 在 年 月 是Java最近的一次发布 J SE (内部版本号 ) 代号 Tiger 现已提供公开下载 Tiger包含了从 年发布 版本以来的最重大的更新 其中包括泛型支持 基本类型的自动装箱 改进的循环 枚举类型 格式化I/O及可变参数 Java虚拟机(JVM)是一个软件规范 相关软件有责任遵守它 以运行编译为Java字节码的程序 JVM是一个抽象的计算机制 并独立于 *** 作系统 具有编译后的程序体积小 可防止执行恶意代码等特点 其没有预先假设基于任何特定的实现技术 不管是硬件还是 *** 作系统 通常我们有几个常用的JVM软件 其 位与 位版本性能有所不同 但它们都包括JIT编译器和垃圾回收功能(GC) JIT编译器从JDK 开始就是JVM的一部分了 当时Java只是用于浏览器客户端动态效果显示的一种技术 JIT编译器实现了程序执行之前Java字节码到硬件机器码的动态翻译 其背后的思想在于 相比Java源代码 字节码更小也更容易编译 但付出的代价是需要在Java字节码编译为机器码时花上一点时间 但与直接把Java源代码编译为机器码相比 时间还是少得多的 在 位与 位的JVM中 相应的JIT在把Java字节码编译为最终的机器码时 所花的时间稍微有所不同 但还能进行一些优化 另外 在IBM与Sun这两个版本的客户端与服务端程序上 总体性能也会有所不同 垃圾回收是一种自动内存管理系统 它会收回对象不再需要使用的内存 从软件工程的角度来看 垃圾回收最大的一个好处就是 程序员不用再 *** 心那些低级的内存管理细节了 同时 垃圾回收也去除了源代码中两个最大的bug 内存未释放(内存泄漏)与过早释放(指针崩溃) 内存回收在Java程序运行期间占了一个很重要的部分 因为它必须被经常执行以释放对象不再访问的Java堆 由于在 位与 位平台上 Java堆中的数据大小会有所变化 所以会因为 位与 位JVM的性能差异 导致相应垃圾回收的性能也会有所不同

位背景介绍 位计算有几个重要组成部分 第一就是 位寻址 实际上 位寻址是通过 位整数寄存器达到的(或RISC中所指的通用寄存器) 位寄存器允许 位的指针装入到单个的寄存器中 而 位的指针 才是可以寻址访问更大内存的实质所在 当 位处理器只能访问到 字节或 GB内存时 位处理器理论上却可寻址访问 字节或 × GB内存 在现代的 位系统中 可寻址的内存的实际限制通常比理论值低一点 具体依赖于特定的硬件架构和 *** 作系统 举例来说 在基于Linux的 *** 作系统中 受限于当前Linux内核数据结构的设计 可寻址的内存最多为 字节或 GB 位计算的第二个重要方面 就是 位整数运算 要提醒的是 这可不是简单地因为有了可存储更多更大整数量 更宽的 位整数寄存器而带来的必然结果 其最直接的影响就是对那些需要处理密集大数值整数运算的程序而言 可带来性能上的飞跃 第三个方面 即 位计算的特性 是 位 *** 作系统与程序的应用 相关的软件必须全面支持硬件的 位特性 包括 位寻址和运算 通常还有一些附带的好处 如 可 *** 作更多更大的文件 管理更大的磁盘等等 位计算所带来的影响 目前已在许多程序中得到了体现 数据库服务器现在可寻址更大的内存 以维持更大的缓冲池 数据缓存 或在内存中进行排序以减少相关的I/O *** 作 也能给每个用户分配更多的内存 支持更多的用户 或对更大的数据文件进行 *** 作 仿真或其他计算密集的程序也将从中受益 如 现在可以在内存中分配更大的数组了 最后 别忘了还有大量的Java程序 J EE应用服务器 现在也能充分享受到 位计算所带来的好处了 位计算的主要缺点是 与它们 位的兄弟相比 位二进制文件一般都更大 因此 最终生成的机器码体积也更大 在系统缓存与旁路转换缓存(TLB)大小不变的情况下 可能会同时降低两者的命中率 这就是说 在一定程度上性能会有所损失 性能评测 此处用于测试 位与 位JVM性能的系统 是两台 位双CPU工作站 一台是基于AMD 技术的Opteron系统 而另一台是基于PowerPC 的Apple Power Mac G 两台工作站都分别运行基于Linux的 位 *** 作系统 受测试的JVM分别来自于IBM和Sun 将使用SPEC的SPECjvm 和SPECjbb 来测试相应JVM的性能 其中SPECjvm 使用了以下项目测试客户端性能 ·_ _press 一个流行的压缩程序 ·_ _jess 一个Java版的NASA CLIPS基于规则的专家系统 ·_ _db 数据管理基准测试软件 ·_ _javac JDK Java编译器 ·_ _mpegaudio 一个MPEG 音频解码器 ·_ _mtrt 一个对图像文件进行处理的双线程程序 ·_ _jack 一个分析程序生成器 SPECjbb (Java商业基准程序)是一个用于服务端的基准测试程序 其模仿了三层体系结构 是一个通用类型的Java服务端应用程序 通过运行SPECjvm 以秒为单位记录了每个基准测试的运行时长 时间越短越好 所有SPECjvm 测试的堆大小因JVM而有所变化 从最小值 MB至最大值 MB 在SPECjbb 测试中 记录了在三种不同堆大小时的每秒执行 *** 作数 更高的值代表更高的性能 每一个测试程序都运行三次 取成绩最好的一次作为最后的结果 图 与图 显示了在AMD 平台上 Linux版本的Sun Java Standard Edition Development Kit (J SE )在SPECjvm 和SPECjbb 中 位与 位的性能测试结果 在SPECjvm 测试中 只有三项 _ _press _ _mpegaudio _ _jack 在 位版本的JVM上比 位表现出更佳的性能 在SPECjbb 中 位版本的性能只在有足够堆大小的情况下 才表现出更高的性能 其中在堆大小为 MB时 因为某些活动数据在 位JVM版本中体积更大 导致垃圾回收动作更频繁 从而降低了程序性能

图 图 图 与图 显示了在AMD 平台上 Linux版本的IBM Developer Kit for Linux Java Technology Edition Version GA在SPECjvm 和SPECjbb 中 位与 位的性能测试结果 其中 基准测试程序中有三项 _ _db _ _javac _ _jack 在 位环境下表现出了更佳的性能 另外 在SPECjbb 测试中 当面对三个不同大小的测试堆时 位IBM版本的JVM都没有表现出比 位版本更好的性能 图 图 图 与图 显示了在PowerPC 平台上 IBM Developer Kit for Linux Java Technology Edition Version GA在SPECjvm 和SPECjbb 中 位与 位的性能测试结果 此处 在所有SPECjvm 和SPECjbb 的测试中 位JVM的性能都不及 位平台 图 图 结论 基于运行Linux *** 作系统的PowerPC 平台的测试结果 表明如果在此平台上使用IBM的JVM 那么 那些不需要 位特性的程序 还是让它们运行在 位JVM中吧 因为在此平台的所有测试结果中 位JVM的性能都比 位平台低 而基于运行Linux *** 作系统的AMD 平台的测试结果 表明不管是Sun还是IBM的JVM 位与 位的性能都在伯仲之间 要注意的是 性能的差异是依赖于具体的应用程序与JVM的 如果需要最佳性能 就必须在某个特定的执行环境中测试某个特定的程序 以评价转换到 位所带来的潜在性能提升 有几件事情需重点注意 第一 尽管SPECjvm 与SPECjbb 都是工业标准的基准测试程序 但它们的测试范围有限 因此 就测试结果而言 只对一部分的Java程序正确 而不是所有 第二 随着 位计算越来越被人们接受 我们期待 位程序会有所改进 包括 位JVM 也许其在将来会大幅提高性能 第三 此处只组合测试了几种特定的硬件平台 *** 作系统与JVM 因此 如果要进一步地说明问题 恐怕只有在 位Windows XP/ 及 位Mac OS X上的进行JVM基准测试了 lishixinzhi/Article/program/Java/hx/201311/26587

引言

有人说,Java确实过于臃肿,经常“小题大做”。但PHP、Nodejs扩展方面短板太明显,做小应用可以,大型应用就玩不转了。另外,JavaEE领域有太多优秀框架可以解决开发效率的问题,事实上借用Spring等框架,开发的效率丝毫不亚于PHP。

互联网时代的Java开发者,很多都不是基于Servlet和EJB来开发Web应用,而且WebLogic、WebSphere也只会存在于大公司的存量系统中,互联网公司的Java都是Tomcat的世界。

那么,微服务能完全弥补JavaEE的短板吗对于JaveEE来说,微服务扮演的,究竟是拯救者还是掘墓人的角色

在Java问世之初,包括IBM、BEA、Oracle在内的一些巨头公司,看到了Java作为一门杰出的Web编程语言可能给他们带来的巨大商机。那么如何通过一门编程语言来赚钱呢答案就是,使用这门语言构建复杂无比的服务器,让那些大公司支付一大笔费用来购买这些服务器。于是紧接着就出现了JavaEE规范、JSR规范,以及WebLogic、WebSphere等服务器中间件。

在这些服务器上面部署了大型的程序包,它们运行缓慢,消耗大量的内存。基于这些容器的开发和调试对开发人员来说简直就是噩梦,作为对他们的补偿,他们从雇主那里获得了丰厚的报酬。

因为耗资巨大,几乎找不到一家公司可以使用合理的费用长时间地支持Java。如果你要用Java构建一个网站,你必须支付一大笔费用来运行这些服务器,哪怕你只用到了Servlet容器。在很长一段时间里,Java被用在企业和公司里,因为只有这些大公司能够负担得起数百万美元的服务器费用,并为那些企业级开发人员支付高额的薪水。

RodJohnson在2003年发布了Spring框架,Spring提供了IoC和对POJO的支持,帮助开发人员逃脱EJB魔掌。开发效率因此得到大幅的提升,大量开发人员转向Spring,把EJB丢在一边。应用服务器开发商看到了这一点,他们在JavaEE5里提供了一些可以减轻开发人员负担的特性。可惜的是,Spring被一路追捧,人们几乎把它跟JavaEE容器混为一谈,它仍然运行在JavaEE的Servlet容器里,这些容器沿用的是十年前的设计,并没有考虑到多核CPU和NIO。

在这期间,PHP奋起直追。PHP使用更少的内存和资源,得到很多公司的支持。一些CMS平台,比如WordPress、Drupal等都是基于PHP构建的,这些平台吸引了大批PHP开发人员。不过,虽然PHP仍然是现今最流行的编程语言,但它也有自己的短板。它运行速度不是很快,而且难以横向扩展。

2009年,RyanDahl启动了Nodejs项目,它支持异步非阻塞的、基于事件驱动的I/O。如果服务器的线程使用得当,Nodejs可以极大地提升响应速度,单个服务器的吞吐量可以媲美一个JavaEE服务器集群。Nodejs是一个很好的作品,但它也有自己的局限性。Nodejs难以扩展,也难以与遗留的系统集成。

2014年,Undertow出现了,它是一个基于Java的非阻塞Web服务器。从#的测试结果来看,在一个价值8000美金的戴尔服务器上,它可以每秒钟处理几百万个请求,而谷歌需要使用一个集群才能处理一百万个同样的请求。它是轻量级的,它的核心部分只需要1M内存,它还包含了一个内嵌的服务器,这个服务器使用不到4M的堆内存。

基于UndertowCore构建的LightJavaFramework是一个微服务容器,它支持设计驱动及生成代码,并支持运行时安全和运行时验证。

JavaEE厂商多年前,JavaEE厂商,比如Oracle和IBM,他们花费数亿美元开发应用服务器(WebLogic和WebSphere),这些服务器以数百万的价格卖给了大型组织。但现在这些服务器卖不动了,因为JBoss迅速抢占了市场份额,Oracle对JavaEE的支持正在走下坡路:

#/story/16/07/02/1639241/oracle-may-have-stopped-funding-and-developing-java-ee

随着微服务越来越多地受到关注,这些应用服务器很难有好的销量,因为这些服务器更适合用来部署单体应用。有一个包含了数百个EJB的应用,为了在WebLogic上测试一行代码改动,居然用了45分钟时间。

JavaEE客户

从客户角度来看,耗费巨资购买这些服务器是不值得的,因为JavaEE所承诺的未必都是真的。一个为WebSphere开发的应用无法部署在WebLogic上,所以你需要花更多的钱去升级服务器,因为厂商可能不再支持旧版的服务器,而这样的更新会花费你数百万美元。

于是一些聪明人不禁要问,为什么我们要把应用部署在这些庞然大物上为什么我们要把应用打包成一个ear包或war包,而不是jar包为什么我们不能把大型的应用拆分成更小的块,让它们可以独立部署和扩展

微服务

微服务是这些问题的解药。Wikipedia把微服务定义为“一种软件架构风格,复杂的应用由一些独立的进程组成,这些进程使用与语言无关的API进行交互。这些进程服务规模很小,高度离散,聚焦在一个很小的任务上,使用模块化方式来构建系统”。

微服务架构让构建应用变得更加容易,而且应用被拆分成单独的服务,这些服务可以被任意组合。每个服务可以被独立部署,也可以被组合成一个应用。这些服务还可能会被其他应用依赖。它加快了服务的开发速度,因为只要定义好接口,服务可以并行开发。

微服务具备d性和伸缩性。微服务不只依赖单个服务器和部署,它们可以被发布到多个机器上,或者多个数据中心及其它任何可用的区域。如果一个服务失效,可以启动另外一个。因为整个应用被分解成了微服务(小型服务),可以很容易地对其中某些热门的服务进行横向扩展。

如果你曾经使用过COM、DCOM、CORBA、EJB、OSGi、J2EE、SOAP和SOA等,那么你就会知道服务和组件并不是什么新生事物。企业在使用组件方面存在的一个最大问题是他们依赖大型的硬件服务器,并在同一个服务器上运行很多应用。我们有EJB、WAR包和EAR包,以及各种组件包,因为服务器资源太过昂贵,要尽可能地物尽其用。

不过从最近几年的发展情况来看,之前的方式有些落伍。 *** 作系统服务器一直在变化,虚拟资源可以被当成组件发布,比如EC2、OpenStack、Vagrant和Docker。世界变了。微服务架构看到了这种趋势,硬件、云技术、多核CPU和虚拟技术也在发展,所以我们要改变以前的开发方式。

在开始新项目的时候不要再使用EAR包或WAR包了。现在我们可以在Docker里运行JVM,Docker只不过是一个进程,但它可以表现得像一个 *** 作系统一样。Docker运行在云端的 *** 作系统上,而云端的 *** 作系统运行在虚拟机里,虚拟机运行在Linux服务器上。这些服务器不是归谁所有,而是被很多互不相识的人共享。如果出现流量高峰怎么办很简单,使用更多的服务器实例。这就是为什么要把Java微服务运行在一个单独的进程里,而不是JavaEE容器或servlet容器。

微服务一般会提供基于>

使用微服务架构的应用程序应该是模块化、可编程和可组合的。微服务之间可以相互替换。应用程序的局部可以被重写或改进,而不会影响到整个应用。如果所有的组件都提供了可编程的API,那么微服务之间的交互就会变得更简单(永远不要相信那些不能通过curl访问的微服务)。

随着微服务逐渐流行起来,很多厂商开始尝试把他们的JavaEEWeb服务转成微服务,这样他们就可以继续卖他们的过时产品,APIGateway就是这些厂商中的一个。

JasonBloomberg是Intellyx的主席,他在一篇文章里指出了传统Web服务和微服务的区别,并对把传统Web服务转成微服务的趋势提出了质疑:

#/dangers-microservices-washing-get-value-strip-away-hype

微服务不是企业服务总线里的Web服务,也不是传统的面向服务架构,尽管它沿袭了SOA的一些基本概念。从根本上来说,微服务跟SOA是不一样的,因为整个环境已经发生了彻底的转变。

微服务架构的环境是没有边界的:端到端,基于云的应用程序运行在完全虚拟和容器化的基础设施上。容器把应用程序和服务组件化,DevOps为IT基础设施提供框架,帮助自动化开发、部署和管理环境。

虽然容器对微服务来说不是必需的,不过微服务可以很容易地运行在容器里。况且,把非微服务的代码部署在容器里不是一个明智的选择。

Docker和其他容器技术在某种程度上已经被视为微服务的最好伴侣。容器是运行微服务的最小资源子集。Docker简化了微服务的开发,让集成测试变得更简单。

容器有助于微服务开发,但不是必需的。Docker也可以被用来部署单体应用。微服务与容器可以很好地相融并进,不过微服务包含的东西远比容器多!

结论

应用开发的风格这几年一直在变化,而微服务变得越来越流行。大公司把大型应用拆分成可以单独部署的小型应用,这些小型应用被部署在云端的容器里。开源微服务框架LightJava为这些运行在容器里的微服务提供了很多特性,它支持设计驱动,开发者只需要把注意力专注在业务逻辑上,剩下的事情可以由框架和DevOps流程来处理。

那么问题来了,你怎么看

jvm入门教程。
一、写在前面;首先,本篇文章并没有涉及原理,而是在笔者撸了《深入理解Java虚拟机》好几遍的基础上讲解自己的经验,从一个新手到现在明白JVM是个什么玩意,怎么去理解和明白,讲解这样一个经验而已。这篇文章并对JVM并没有挖掘得很深,在下目前暂时也没有这个能力,只是以通熟易懂的方式,让读者理解JVM是个什么玩意。下面开始我的讲解。
二、谁说人神不得相爱——Java的跨平台;理解Java的跨平台特性,是对JVM最直观的认识。所谓的“一次编译,到处运行”,为什么C/C++却不能实现呢?这一类语言直接使用物理硬件(或者说 *** 作系统的内存模型),那么不同系统之间的内存模型是不同的,比如说Linux和Window,这就意味,在Window编译好的代码,却不能在Linux上运行。《深入理解Java虚拟机》记录说,Java虚拟机规范中试图定义一种Java内存模型(JMM)来屏蔽掉各种硬件和 *** 作系统的内存访问差异,以实现让Java程序在各种平台上都能达到一致性的并发效果。举个现实的例子,一个只会听说中文的人,要如何和一个只会听说英文的人交流,在Java的世界里,采用的方式即是给两边的人各配一名翻译官(JVM),所以,这就是为什么JVM要有window版本,也要有Linux版本。众所周知,Java的程序编译的最终样子是class文件,不同虚拟机的对每一个class文件的翻译结果都是一致的。而对于C/C++而言,编译生成的是纯二进制的机器指令,是直接面对计算机系统的内存,但是,java程序的编译结果是面向JVM,是要交付给JVM,让他再做进一步处理从而让计算机识别运行,这就是所谓的“屏蔽掉各种硬件和 *** 作系统的内存访问差异”。这里的特点又和面向对象推崇的面向接口有着不可描述的关系,我只需要有这么个规范,不需要去知道接触你的底层原理实现。
三、活在梦里的真实——虚拟机;JVM,全称JavaVirtualMachine,英文为Java虚拟机,简单的探讨一下虚拟机这三个字,对后面的学习也是挺舒服的。百度百科描述说,“虚拟机(VirtualMachine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统”,但是虚拟机本质还是该计算机系统的一个进程,可以类比香港澳门具有高度自治,但本质上他们还是属于中国的。为了方便描述,我们把整个计算机当成一幢大楼,而虚拟机则是某一个楼层。大楼划分了一个区域给一个楼层,让这个楼层自己管理自己,也就对应着,计算机划分了一个内存给JVM,让JVM自己管理自己。下面这张图是笔者的阿里云服务器上的内存使用情况,可以看到JVM足足占用了接近500M的内存。那么问题来了,JVM要这么多的内存干什么,这里面又是怎么划分?
四、你来到我的世界里——内存;在现阶段无论什么编程语言,都是由人类设计发明的,编程语言对于人类来讲,是方便自己实现目的的工具之一,所以,编程语言看似是全新的东西,但是这里面处处都可以看见人类思想的影子,都可以从现实中找到相似的例子。接着上面的例子,JVM是作为某一个楼层,单独占有了一大块区域(内存)。这个楼层中,有主厅,客厅,客房,这四个之间的区别之一就行,主厅和客厅是公有的,而主房和客房是私有的,这里对应到JVM层次上即是,有某几块内存,是无论是谁访问,有多少人(线程)访问,这些共有区域都可以为他们服务,而客房,私有区域,假定我们这个楼层比较牛逼,来了多少个客人,就会单独为他们建造每一件客房,每个客人都有自己私有区域,A客人是进不了B客人的房间。对应的JVM的层次,即是JVM运行时数据区域划分为两大块,线程隔离的区域和线程共享的区域。我们可以简单的理解为,每个客人即是一条线程。具体对应的区域又是如何划分的,又有什么作用,这里只能从概念上理解和记忆了,传送门在此轻松认识JVM运行时数据区域。
五、离开我,却没有带走你的痕迹——什么是垃圾;回想起小时候,很多小伙伴都会一起结伴过来我家玩耍,虽然大家玩得很开心,等到了时间点之后,他们就拍拍屁股走人,留下我家里一片狼藉,这个时候如果我不收拾一下垃圾的话,我老妈估计就要来拍拍我的屁股了。客人(线程)同样如此,我来过你的世界,总会留下属于我的痕迹,是不是垃圾,就要看你自己如何判定了。这里就引出另一个问题,我怎么判断是哪个才是垃圾,哪个不是垃圾,只不过是玩耍的时候,我或者小伙伴随手把老妈的戒指扔到地上而已。站在人类的视角上看,一眼就知道哪个是垃圾,哪个不是垃圾,但是计算机可不是这样,计算机有些时候确实不如人类,明明人类一眼或者几秒能完成的事情,要让计算机同样能够完成对应的功能的话,需要付出千万倍的代价才能够实现。笔者的老妈在家里收拾垃圾的时候,为了确保扔掉的东西是垃圾,她会将这个东西,一个一个问家里的每个人,这个东西是不是你的,你还要不要,当没有一个人承认说这个东西是属于他的时候,老妈就将这个东西视为垃圾,当有人说这个不是垃圾,是他的宝贝的时候,我老妈就这个东西标记一下。JVM采用的是类似的做法,每个对象到GCROOT都有一定的联系和路径可达,当某个对象,对于GCROOT不可达(即没有人说这个东西是属于他的)的对象,JVM则判定为垃圾。JVM里称此行为是可达性分析。finalize的作用:假设一个本子已经被老妈认定为垃圾了,但老妈在扔掉垃圾的时候必须先经过一个程序,即finalize,假如在这个程序过程中,我突然想起这个本子对我还是有用的,那么这个本子就不会被认定为垃圾,从而继续保留在内存中。
六、我要怎样忘了你是谁——垃圾回收算法;知道什么是垃圾,找到了垃圾的位置,接下来的问题是我要怎么处理这个垃圾,即垃圾回收。我要怎样忘了你是谁,关键是要怎么字,这个动作是怎么发生的。标记清除:在这个楼层中,垃圾四处都有,甚至散乱在非垃圾之间或者周围,即然我老妈已经给有用的东西做个标志,那么这就意味着我老妈只需要清除那些没有标识的东西。标记清除的做法形象成就是我老妈拿着垃圾桶,从头到尾,看到垃圾就把他扔到垃圾桶里面。这种做法无疑是最简单的,但是带来的后果也是很明显的,空间碎片太多。这里的空间碎片又要做如何理解,每个物品(每个对象)都是需要占据着一定的的面积(即内存),他要站住脚跟嘛,但是如果空间碎片的太多,就会导致大的物品来临的时候,区域(内存)不够用,就会再次引发垃圾回收(意味着你打游戏的时候可能要停顿个几秒)。再举个现实中的例子,打包行李箱的时候,随随便便,散乱的放置东西,行李厢很容易被撑满,这个时候你还想放一双鞋进去,你会发现空间不够用,只能把所以东西都倒出来,整整齐齐的,从上到下从左到右的放置物品。对于空间的利用率,整齐的做法比散乱无章的行为更来得高,这就引出了另外一个做法,标记整理算法。标记整理:你见过有谁扫地的时候,看到垃圾就直接把扫到扫帚了里面,看到就扫。不存在的!人是有惰性的,所有总会找到更高效的做法,更习惯的做法是将垃圾扫到一起,再统一将其扔到垃圾桶中。复制:这个算法就有点奢侈了,不管这个内存里有多少垃圾,我老妈都统一将他们扔掉,然后重新再买一次那些我们还需要用的物品,俗称复制。因此,如果存活对象太多,这个算法是不适合的(想想就知道了--),其二,JVM里面需要将可用内存分为两半,一半供目前使用,一半供复制后的对象使用。

分析了当前比较流行的几个不同公司不同版本JVM的最大内存,得出来的结果如下:公司JVM版本 最大内存(兆)client 最大内存(兆)serverSUN 15x 1492 1520SUN 155(Linux) 2634 2660SUN 142 1564 1564SUN 142(Linux) 1900 1260IBM 142(Linux) 2047 N/ABEA JRockit 15 (U3) 1909 1902除非特别说明,否则JVM版本都运行在Windows *** 作系统下通过这个表想说明的是,如果你的机器的内存太多的话,只能通过多运行几个实例来提供机器的利用率了,例如跑Tomcat,你可以多装几个Tomcat并做集群,依此类推。堆(Heap)和非堆(Non-heap)内存按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 堆内存分配JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70% 时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。 非堆内存分配JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 JVM内存限制(最大值)首先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限大的话,JVM内存的最大值跟 *** 作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的 *** 作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为15G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。所以说设置VM参数导致程序无法启动主要有以下几种原因:1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize;2) -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前 *** 作系统最大内存限制,或者实际的物理内存等等。

BEA JRockit Java虚拟机(JVM)所带来的不仅仅是性能的提升 本文探讨了JRockit R 版本可用的一些管理和使用方面的特性 概述了JRockit Mission Control分析工具套件 JRockit Management Console的试验性headless模式以及使用Ctrl Break Handler JRCMD 堆视图和code coverage与JVM进行交互

简介JRockit JVM不只是快 它还和JRockit Mission Control一起 组成一套执行运行时分析和内存泄漏检测的分析工具 JRockit Management Console包含在JRockit JDK中 本文将探讨JRockit Management Console的一种试验性的headless模式 它可以用于与来自命令行的基于JRockitJMX的管理代理进行交互 Ctrl Break Handler提供了一种向JRockit发送各种高级命令的方法 甚至是在它启动后 这些命令甚至可以远程调用 我在后文中会提及 最后 我探讨了试验性的code coverage JRockit开箱即用地提供了该特性

关于BEA JRockit的更多信息 参见dev dev网站的JRockit Product Center

首先我将快速概述一下JRockit JVM可用的已确定的管理工具 然后我会转向缺少文档的试验性管理特性

JRockit Mission ControlJRockit R 版本引入了JRockit Mission Control工具套件 它包含的工具可以进行监控 管理 分析和消除Java应用程序内存泄漏 而不会引起通常与此类工具相关联的性能开销 Mission Control的低性能开销是因为使用了作为JRockit常规适应性动态调优的一部分而收集的数据 这还可以消除工具使用字节码装置修改系统执行特性时发生Heisenberg异常的问题 JRockit Mission Control功能可以根据需要随时可用 低性能开销也只在运行工具时有效 这些特征使得JRockit Mission Control成为专门用于生产中系统的工具

JRockit Mission Control中包含以下工具

JRockit Management ConsoleJRockit Management Console用于监控和管理多个JRockit实例 它捕获并显示关于垃圾收集器(GC)暂停 内存和CPU使用的实时数据 以及部署在JVM内部MBean服务器上的所有JMX MBean的信息 JVM管理包括对CPU相似性 垃圾收集策略和内存池大小的动态控制 JRockit Runtime AnalyzerJRockit Runtime Analyzer(JRA)是一个随需应变的 动态记录器 它生成关于JVM和正在运行的应用程序的详细记录 然后可以使用JRA应用程序对记录下来的配置文件进行离线分析 所记录的数据包括对方法和锁定的分析 还有垃圾收集统计信息 优化决策以及对象统计信息 JRockit Memory Leak DetectorJRockit Memory Leak Detector工具用来发现和查找内存泄漏原因 Memory Leak Detector的趋势分析器可以发现非常缓慢的泄漏 显示详细的堆统计信息(包括指向泄漏对象和分配位置的引用类型和实例) 并快速找出泄漏原因 Memory Leak Detector使用先进的图形化表现技术 以便更容易定位和理解有时比较复杂的信息

关于JRockit Mission Control的更多信息 可以阅读文章An Introduction to JRockit Mission Control 或者访问dev dev网站的JRockit Mission Control

JRockit Management Console的Headless模式(试验性)

JRockit Management Console是监控JRockit运行的工具 它包括两部分 一个运行在JVM进程中的JMX代理 一个使用图形化用户界面的独立客户端(关于它以及其它方面的更详细的信息 请参见An Introduction to JRockit Mission Control) 其中 用户界面可以绘出部署在所连接的Java虚拟机中的任何MBean的数值属性的图形 图形密集的应用程序对资源的消耗可能会相当厉害 JRockit Management Console也不例外 可以引入text only(纯文本)模式 以便使用Management Console的通知功能和数据收集工具而不会导致整个GUI的开销

headless控制台引入了大量新的命令行参数 这同样适用于控制台的GUI版本 参数包括

参数 描述 headless 以headless模式启动控制台(不会加载与GUI相关的类) settings <settings file> 使用指定配置文舳H绻讷UI模式启动 并且该文件不存在 那么它将在关闭Management Console时创建 connectall 连接配置文件中所有可用连接(即原先使用GUI添加的) connect <connection > <connection > < > 使用GUI连接配置文件中可用的指定连接 autoconnect 自动连接到运行在启用JRockit发现协议(JRockit Discovery Protocol JDP)的管理服务器上的任何JRockit uptime <time in seconds> 将控制台运行一段指定的时间 然后自动关闭它 useraction <name> <delay in seconds> <period (optional)> 经过指定的时延后运行指定的用户动作 如果不指定period 动作将只执行一次 如果指定 动作将每过<period>秒就执行一次 version 打印Management Console的版本信息 并退出 locale <language> <country (optional)> 使用特定的地区启动控制台 比如 locale ja JP将以日语启动控制台(JRockit R 可用)

这里给出一个以headless模式启动Management Console的例子 读取指定配置文件 尝试连接所有已指定的JRockit 使用JRockit发现协议(JDP 下文讨论)积极查找新的JRockit 秒后将以每分钟一次的间隔向所有连接的JRockit发送Ctrl Break命令 一小时之后自动关闭 以前加入指定连接的所有通知规则(不管是通过使用GUI还是通过直接编辑配置文件添加的)将生效

java jar ManagementConsole jar headless settings C:\Headless\consolesettings xml connectall autoconnect uptime useraction ctrlbreak

用户动作是可以与JRockit Management Console上的一组连接进行交互的插件类 同样使用控制台配置文件来存储配置数据 用户动作显示在JRockit控制台图形用户界面的Plugins菜单下 headless模式中也可用 随控制台提供了两个默认用户动作 jrarecording用户动作 对连接的JRockit启动JRA记录 ctrlbreak用户动作 向连接的JRockit发送Ctrl Break命令(参见本文中关于Ctrl Break Handler和JRockit运行时分析器的小节) 要指定特定用户动作的参数 可以使用GUI进行配置 也可以编辑Management Console配置文件 后者可以在<user home>/ManagementConsole/ManagementConsole/consolesettings <version> xml文件中找到

编写自己的用户动作很容易 首先创建一个AbstractUserAction的子类 该示例演示了如何创建一个从所有连接的JRockit获取线程堆栈转储的用户动作

package example useractions; import java io IOException; import java util List; import nsole rjmx CommonRJMXNames; import nsole rjmx RJMXConnectorModel; import nsole useractions AbstractUserAction; / This is a simple user action getting stackdumps from the selected JRockits and printing them on stdout @author Marcus Hirt / public class MyUserAction extends AbstractUserAction { public void executeAction(List connections) { for (RJMXConnectorModel connection : connections) { if (connection isConnected()) { try { System out println(CommonRJMXNames getThreadMXBean(connection) getThreadStackDump()); } catch (IOException e) { e printStackTrace(); } } } } }

接下来 需要在consolesettings xml文件中配置部属描述符 以便用户动作对于控制台可用 可以在配置文件中发现user_actions元素 它已经填充了一些user_action元素 示例动作的部署描述符应当以相同的样式输入 描述符看起来会是这样

<user_action> <user_action_class> example useractions MyUserAction</user_action_class> <user_action_name>stackdump</user_action_name> <user_action_menu_name>Stack Dump on stdout</user_action_menu_name> <user_action_description>Gets a stack dump from the selected JRockit(s) and dumps it on stdout </user_action_description> </user_action>

这也使得用户动作在Plugins菜单下的用户界面中可见

当控制台启动或退出时 如果有设置/状态需要从配置文件加载/保存 只需重写exportToXml()/importFromXml()方法 如示例中所示

/ @see nsole util XmlEnabled #exportToXml( w c dom Element) / public void exportToXml(Element parentNode) { super exportToXml(parentNode); XmlToolkit setSetting(parentNode MY_PROPERTY m_myVal); } / @see nsole util XmlEnabled #initializeFromXml( w c dom Element) / public void initializeFromXml(Element parentNode) { super initializeFromXml(parentNode); m_myVal = XmlToolkit getSetting(parentNode MY_PROPERTY DEFAULT_MY_VALUE)); }

注意 用户动作的名称是使用launcher启动参数时将引用的用户动作名称 菜单名是会在GUI菜单中显示的名称 更多的信息请参见user action docs和JLMEXT docs 注意 这只是一个试验性的功能 提供的文档还相当简单 编写定制的通知动作和约束的方式与此类似 更多信息请参见Management Console User Guide

JRockit发现协议(JDP)JDP(JRockit发现协议)是个简单且有效的协议 用于允许JRockit管理服务器向Management Console组播它的存在 下面的两个表分别列出了在服务器端和客户端控制JDP行为的系统属性

管理服务器的JDP属性 系统属性 描述 默认值 jrockit managementserver autodiscovery 启用JRockit发现协议 False jrockit managementserver discovery period 在两个ping之间需要等待多久(以毫秒为单位) jrockit managementl 活跃的跃点数 jrockit managementserver discovery address 所使用的组播地址 jrockit managementserver discovery port 所使用的组播端口

Management Console的JDP属性 系统属性 描述 默认值 nsole preferences jdp port 用于JRockit发现协议的端口 nsole preferences jdp address 所使用的组播地址

这里给出了在服务器端启用JDP的情况下 启动JRockit需要最少参数的示例

java Xmanagement Djrockit managementserver autodiscovery=true<your program>

Ctrl Break Handler

您是否曾经希望在JVM启动后可以使用一种轻松的方式与其交互?假如说您忘记添加 Xmanagement选项来启动管理服务器 或者您想改变运行系统中GC的冗余级别 这些现在很容易通过重新配置Ctrl Break Handler来完成 而且它不只是打印堆栈跟踪

用法

创建一个名为ctrlhandler act的文件 向ctrlhandler act文件添加命令(参见下文命令列表) 以 stop 结束文件 这是结束文件分析的保留命令 按下ctrl break 每一个命令都将以出现的顺序执行

JRockit首先会在当前工作目录查找该文件 如果未找到 JRockit将在JVM目录中查找 如果仍然没有的话 JRockit将回退以生成一个常规的线程堆栈转储 JRockit将在每次按下ctrl break时读取act文件 因此用户可以在方便时重新配置该文件 而同时JRockit仍在运行

这里给出一个示例act文件 它首先打印时间戳 然后是用于启动JRockit的命令行 最后是一个线程堆栈转储 它还包括可以用于act文件的有用命令的列表

# Example ctrlhandler act file timestamp mand_line print_threads stop # set_filename filename=<file> [append=true] # Sets the file that all handlers following this mand will # use for printing You can have several set_filename mands # in a file It takes o arguments: filename and an optional # append to specify if you want to append to the file # or overwrite it Default is to overwrite the file # timestamp # Prints a timestamp # print_threads # The normal thread dump # verbosity [args=<ponents>] [filename=<file>] # Changes the verbosity level normally specified with Xverbose # version # Prints JRockit version information # mand_line # Prints the mand line used to start JRockit # print_object_summary # Prints heap usage statistics (how much heap is used per class) # together with a delta on how much this has changed since # the last invocation of this ctrl break handler # print_memusage # Prints a memory usage report of how JRockit is using # the memory # heap_diagnostics # Prints a detailed report of the heap including ascii graphics # over the heap layout # print_class_summary # Prints all loaded classes # print_utf pool # Print all UTF strings # jrarecording [filename=<file>] [time=<time>] [nativesamples=true] # Starts a JRA recording # run_optfile [filename=<file>] # See OptFile # start_management_server # Starts the new JMX based management agent # kill_management_server # Stops the management agent # start_rmp_server # Starts the old management server (actually the listening # socket that in turn starts servers whenever a connection # is established) # kill_rmp_server # Stops the old management server (actually shuts down the # listening socket) The only reason it isn t named # kill_rmp_server is that stop is a reserved keyword # that stops the parsing of the act file ;) # help [ctrl break handler] # Prints all available ctrl break handlers if no argument # is specified or help for the specified ctrl break handler # memleakserver [port=<port>] # Toggles the memleakserver If it hasn t been started # it will be started If it has already started it will be # shut down The default port is # verbose_referents action=[heap|full|nursery|start|stop] # Print verbose reference information # Parameters: # action=[heap|full|nursery|start|stop] # heap trigger a heap collection and output reference # information # full trigger a full heap collection (clears softly # reached soft referents) # nursery trigger a nursery collection (heap collection # if running without nursery) # start start writing reference information to default # verbose stream # stop stop writing reference information # print_exceptions # exceptions=[true|all|false] stacktraces=[true|all|false] # Enable printing of Java exceptions thrown in the VM # Parameters: # exceptions print exceptions # stacktraces print exceptions with stacktraces # At least one of the parameters is required # Values for the parameters can be true|all|false # true print all exceptions # except java/util/EmptyStackException # java/lang/ClassNotFoundException and # java/security/PrivilegedActionException # all print all exceptions # false don t print exceptions # To turn exception printing off pletely you need to set # exceptions = false even if it was turned # on by stacktraces = true JRCMD 使用JRCMD实用工具是一种新的调用Ctrl Break Handler的便捷方式 可在JRockit发行版的bin目录中找到它 用法 jrcmd <PID> <mand> <parameters>

JRCMD使用JRCMD实用工具是一种新的调用Ctrl Break Handler的便捷方式 可在JRockit发行版的bin目录中找到它

用法 jrcmd <PID> <mand> <parameters>

PID = 要在其中执行Ctrl Break Handler的JRockit进程的进程ID mand = 要执行的Ctrl Break Handler命令 parameters = Ctrl Break Handler的参数

如果不指定选项(或者只指定 P) 那么将显示运行在本地机器上的所有JRockit的进程ID 如果PID设为 那么命令将发送给在本地机器上运行的所有JRockit JVM

要列出特定的JRockit中有哪些Ctrl Break Handler可用 可以使用help命令

jrcmd <PID> help

要想获得某个具体的Ctrl Break Handler的帮助信息 需要在help后添加Ctrl Break Handler的名称 比如

jrcmd help kill_management_server

也可以使用JRCMD列出指定进程的性能计数

jrcmd <PID> l

远程调用Ctrl Break Handler可以使用JRockit Management Console来远程调用Ctrl Break Handler 存在一个对JRockitConsoleMBean的 *** 作 称为runCtrlBreakHandlerWithResult JRockit Management Console可以从属性浏览器调用对MBean的 *** 作 这里有关于如何调用Ctrl Break Handler的逐步描述

连接到一个运行中的JRockit 右击该连接 选择Browse Attributes 展开 jrockit domain文件夹 选择JRockitConsole MBean 单击operations选项卡 查看可用 *** 作 单击String parameter参数按钮 找到runCtrlBreakHandlerWithResult *** 作 输入希望执行的Ctrl Break Handler名称 语法与ctrlhandler act文件相同 按下OK 按下Execute按钮 执行 *** 作

试着输入 help 作为参数 将会列出所有可用的Ctrl Break Handler 如图 所示

图 从JRockit Management Console调用Ctrl Break Handler(单击查看大图)

堆视图(试验性)当分析应用程序如何使用某种垃圾收集策略时 在每一次GC后对堆进行快照将会非常有帮助 这有助于开发人员研究数据 比如碎片/压缩以及算法通常如何执行 但是快照中包含如此多的数据量以至于查看它没有什么意义 因此JRockit团队开发了一个提供图形化表示的小工具 以便更好地进行说明

图 显示了一个快照的例子(使用的是一个非常早的JRockit 预发布版本)

每一排表示一次垃圾收集 左边是开始的堆 右边是结束的堆 堆显示的右边是一个可配置图形 实心白 域表示空白堆 黑 域是充实区(也就是填充了对象的区域) 浅灰 域是碎片区 红色 **和绿 域是可配置图形 可以从命令行指定在可配置图形中显示什么 该工具依然很粗糙 对于用户也不够友好 不过毋庸置疑它对JRockit的终端用户非常有用 所以这是一个非常不错但是不能通用的工具

code coverage(试验性)很多开发人员在以某种方式使用他们的应用程序时 使用code coverage分析来研究诸如代码库中的多少以及哪些部分正在运行之类的状况 测试人员喜欢使用code coverage来度量测试套件覆盖应用程序的比例 但是 对于大型应用程序 由code coverage工具所引起的性能开销通常是被禁止的

JRockit内置了高性能的行code coverage 当启用code coverage运行时 代码将由记录行命中的捕获器生成 一旦某行被命中并记录 就删除捕获器 JRockit可以继续以接近全速的速度运行

要使JRockit记录code coverage数据 必须指定一个命令行选项

用法 Xcodecoverage

可以使用以下系统属性来控制该行为

系统属性 描述 decoverage filter=<filterspec> filterspec是个以分号(Windows)或冒号(Linux)隔开的筛选器字符串列表 它定义哪些类应当被覆盖 以 开头的筛选器字符串会被视为不应当覆盖的类

示例 decoverage filter=java/util/Hashtable;/bea/; /bea/bla

decoverage filterfile=<filename> 设置包含筛选器定义的文件的文件名 文件格式为每行一个筛选器字符串 decoverage outputfile=<filename> 设置存放输出的文件 如果写入<filename>_ 输出文件不能被打开 那么将尝试<filename>_ 以此类推 在多个JVM共享一个公共命令行的情况中 这可能会很有用 decoverage testid=<id string> 设置初始测试标识符 decoverage verbose 使code coverage更为详细 适用于在覆盖文件(均是纯文本文件)中执行文本比较 decoverage appendoutput 设置对输出文件的写入为追加而不是覆盖

这里给出特定于code coverage的参数 用于生成如下图中所示的数据

Xcodecoverage decoverage filter=/jrockit/console/;/jrockit/mon/ decoverage outputfile=console_coverage txt

在内部 由一个code coverage小工具来解释JRockit所生成的数据 如图 所示

图 code coverage工具的输出示例

lishixinzhi/Article/program/Java/hx/201311/26298


欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zz/12809532.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-28
下一篇2025-08-28

发表评论

登录后才能评论

评论列表(0条)

    保存