adv

Native Agent Vs Java Agent利与弊

软件 用户日志
lx1 (25847)发表于 2016年12月20日 19时13分 星期二
来自部门
许多应用性能管理(APM)厂商在对 JVM运行时性能进行深入分析时,一般使用JVM运行时的接口,而JVM运行时提供两种接口:JVMPT和JVMTI。JVMPI 接口从 Java 5后逐渐被 JVMTI 所取代,且JVMTI接口都允许APM厂商将本地库(通常称作Native Agent)加载到与 JVM 同一个进程中,使得该本地库可以通过本地的 API (C/C++代码)访问 JVM 运行时的状态和应用程序的性能数据。另外,由于该库并不作为 JVM 运行时的一部分,它不会受到 JVM 停止的影响(例如:较长的垃圾收集挂起、运行时错误等),因此能够一直向外部工具传输数据。

Java 5 还引入了一种纯 Java 接口方案(通常称作Java Agent),作为这种本地接口的替代方案。这种方案允许将Java Agent加载到 JVM 之中,并作为 JVM 的一部分运行。其“不利”的一面是,Jva Agent是在 JVM 启动后期才被加载,该Agent是运行在JVM运行时的容器里,它会受到 JVM 挂起或 Java 运行时问题的影响,并且不能报告某些类型的错误信息。

在本博客中我们将主要阐述,为何Dynatrace的工程团队决定采用Native Agent方式结合字节码插码技术(bytecode instrumentation,BCI)的方式,而不是采用基于 Java Agent的方式,来监控应用程序的性能。

对所有的类进行全面、深入的分析

Native Agent能够在任何类加载之前加载。这使Native Agent能够从一开始就采集数据,并可使其不会受到任何约束的,对所有的 Java 代码进行数据采集和控制执行。为能捕获方法级的信息,可利用字节码插码技术(BCI)实现优势互补,而不是依赖于Native接口的回调。这样不仅能对任何类执行字节码插码,还能对核心系统类进行深入分析(java.lang.Object、java.lang.Thread等)。

获得更为详尽的信息

通过JVM native接口,我们可以获得更为详尽的性能信息,例如操作系统的高精度时钟、详细的垃圾收集数据等。由于采用了Native Agent方式,因此不必另外安装用于采集系统信息的程序。而Java Agent很可能无法访问上述数据,因为它运行于 JVM 内的特殊的安全背景环境之中。



在Native Agent内部,我们可以采集到与 JVM 有关的大量信息,例如内存、线程、JVM 崩溃等。尤其对于线程和内存分析,访问 JVM 线程和内存使用情况以及本地线程和内存使用情况有助于性能监测。一旦出现内存不足错误导致崩溃,因为本地进程仍在运行,所以Native Agent仍能采集堆栈中的数据和内存信息。
【线程死锁分析】



对 JVM 的影响轻微

通过本地代码调用JVMTI接口,可以更加有效的获取性能分析的数据,例如,通过线程(Thread)快照的方式获取线程栈信息,而从 JVM 内部的 Java Agent调用JVMTI接口获取此类信息所需的代价要高很多,然而,对线程栈做快照恰恰是定位Java方法执行缓慢的最佳途径,由于对JVM的负载太高,以至于部分Java Agent的APM厂商不得不放弃功能来达到用户对性能开销的要求。



未挂靠 JVM

由于Native Agent没有挂靠(attach)在 JVM 上,因此不会受到 JVM 挂起(特别是与垃圾收集)的影响,可以在 JVM 停止(让进程仍然运行)期间仍采集数据,这样可以帮助我们采集有关垃圾回收所导致的JVM挂起对当前正在执行应用线程的实际影响的信息,而 Java Agent则无法获得这样的信息,因为它受到 JVM挂起的影响,而不能执行自身的代码来收集数据。
总结

Native Agent因为工作原因的不同,导致其与Java Agent相比,拥有明显的优势,具体总结如下: 1. 获取JVM运行时的性能参数。
2. 获取JVM线程栈信息
3. 不受JVM的运行状态影响。
4. 开销更少

本文翻译自:http://apmblog.dynatrace.com/2014/01/15/pros-and-cons-of-using-java-vs-native-agent-for-application-performance-management/

中文内容作者Dynatrace技术专家丁威

评论已经自动封存,请勿再发言论
显示选项 样式:
声明: 下面的评论属于其发表者所有,不代表本站的观点和立场,我们不负责他们说什么。