由于 Android 应用程序在基本上是虚拟处理器的 JVM(Dalvik VM)上运行,并且每个虚拟指令都必须映射到底层芯片组的本机指令,这种映射是否会因这种映射的开销而导致更多的功耗?
这个问题可以扩展到 Java,也可以表述为“Java 应用程序是否耗电更多?”。这就是为什么 Android 手机的电池寿命与其他平台/手机相比如此糟糕吗?
编辑:根据回答,我澄清了一些问题,因为我错误地将 JVM 和 Dalvik 混为一谈。在这个问题中,我谈论 Java 只是为了问它是否耗电更多,如果是,这在概念上是否也适用于 Android,是否会导致电池寿命缩短。
语境:引自维基百科:
- Java 字节码类似于 C 代码的汇编语言。
- 从编译器的角度来看,Java 虚拟机只是另一个具有指令集(Java 字节码)的处理器,可以为其生成代码。
- JVM 是堆栈架构,Dalvik 是进程虚拟机,与 JVM 的虚拟化类型不同,是寄存器架构。
由于 Java 编程语言被编译为字节码(类似汇编)并在虚拟处理器上运行,因此它提供了真正的软件代码可移植性。此外,由于 Linux 有 JVM,并且 Linux 已移植到开放硬件上,因此这种组合可以在整个堆栈中提供真正的应用程序可移植性。
力量:问题本质上可以归结为:对于软件代码或应用程序的同一组功能,有多少百分比的 CPU 时钟周期归因于运行时环境。这是在现代 JVM 的即时编译环境中,如果字节码被编译为底层芯片组的本机指令,则运行时应该仅在 jit 编译期间处于活动状态。那么在运行时环境中会使用多少更多的 CPU 时钟周期,预计这会导致功耗开销。我只对功耗方面感兴趣,而不是与静态类型和构建语言相比的相对性能,并且了解 Java 的优势。可能相关的子问题:
- Java 运行时是否使用 libc 来实现其功能?
- 这些与功耗相关的点是否适用于 Dalvik VM 和 Android?
- 我们不去概括 Android 电池消耗低的问题,也不去谈论屏幕和无线芯片组,而是谈谈 iPhone 5 的电池容量为 1440 mAH,与现代 Nexus 手机相比,这真是小菜一碟。我之所以会产生这种想法(Java、虚拟处理器、指令映射、Android),是因为一位 iPhone 忠实粉丝声称,这可能是他的 iPhone 电池寿命比我的(超棒的)Nexus 更长的原因。
无论如何,感谢以下的回答。
答案1
您的问题基于许多错误的假设。让我试着澄清一下:
您说的是“JVM(Dalvik VM)”。这就像说“飞机(自行车)”一样。这两件事完全没有关系。
您说的是“...基本上就是一个虚拟处理器”。这完全是错误的。不是每次在技术语境中使用“虚拟机”或首字母缩略词“VM”时,它本质上等同于VMware工作站。这是因为 VMware 等产品事实上模拟整个计算机,而不仅仅是 CPU,并且在另一个操作系统上运行一个操作系统。Dalvik VM 确实不是就像那样工作。差得远。
Java 只是一种编程语言。它是语法。Android/Dalvik 程序恰好使用与完全不相关的桌面/服务器编程语言 Java 相同或非常相似的语法,Java 运行在 Java 虚拟机上。理论上,你可以编写与 C 代码速度几乎相同的 Java 代码,因为它们都是高级编程语言。问题在于库调用的实现细节和运行时的设计方式,这与语言的语法几乎没有关系。
说 Dalvik VM、Sun Java Hotspot JVM 或 Java 编程语言语法是造成高功耗的原因,这是过于笼统的说法。原因是,你必须将你谈论的任何内容与其他东西。在最普遍的情况下,当您仅比较两个平台的“最佳情况”功能时,原则上可以制作出与其他平台上的程序一样快甚至更快的 Dalvik 应用程序。除了自动内存管理和 JIT 编译(这些功能如今已成为几乎所有编程环境(包括 iOS 和 JavaScript/HTML5)的标准功能)之外,Dalvik 与 Objective-C、.NET、Ruby、Oracle Hotspot JVM、Python 等几乎没有什么区别。
“Java 很慢”这一看法是由于旧版本的 Java 存在问题,因为它们要么没有即时编译器 (JIT),要么 JIT 的功能非常有限。JVM 有一个即时编译器很长一段时间以来,JIT 编译器一直都是一个难题。JIT 编译器是运行时(例如 JVM)的一部分,它接收独立于处理器的字节码(例如 Java 字节码)并将其编译为 CPU 的本机指令。这个过程在 Java 程序启动时完成,高级 JIT 编译器可以在运行时优化各个函数或指令,以根据观察到的结果提高其性能。例如,如果某个方法每次调用时都返回 true,但从原始字节码中看不出它会这样做,那么 JIT 编译器可以识别出它只是返回 true,并用硬编码值“true”替换函数调用。这只是一个例子。
JIT 编译和运行时动态代码分析技术近年来取得了巨大进步。计算机科学界的许多人认为,再过一二十年,Java、C# 和 Ruby 等动态解释/编译语言中提供的复杂分析将非常先进,在大多数情况下,这些语言将执行快点在运行时比 C 和 C++ 等静态编译语言更高效。这是因为静态编译器通常仅限于在构建时编译代码,并且代码在运行时不会被修改。但在运行时环境中,程序的代码可以重写本身在执行过程中提高执行效率,通过分析代码的性能并进行调整以降低代码的复杂性或 CPU 上运行的指令数量,可以获得巨大的好处。对于频繁调用的代码,执行分析所需的时间投入远远超过重复调用更快代码的性能优势。
需要注意的是,Android Dalvik VM 也包含 JIT,并且它使用的字节码格式与 Sun/Oracle JVM 不同。Dalvik 的 JIT 针对低内存环境进行了优化,并且在运行时性能增强方面非常先进。因此,JVM 和 Dalvik 实现相似的针对各自的基于 Java 的运行时环境进行了优化,但在本质上它们是完全不同的。
不要忘记,Dalvik 本身、Linux 内核、低级系统进程以及 Android 网络浏览器(Firefox 和 Chrome)的核心都是用原生 C/C++ 编写的,因此它们不存在 Dalvik 程序所带来的任何开销问题。这与 iOS 相同。如果您谈论的是纯 Android而不是上面提到的运营商/第三方臃肿的东西,Android 核心的很大一部分是不是使用 Dalvik 编写。
Android 上的应用程序开发人员还可以选择编写本机代码,绕过 Dalvik。如果应用程序开发人员认为 Dalvik 是其代码性能的瓶颈,或导致其耗电量过多,他们可以随意编写 C/C++ 甚至汇编代码,而无需获得 Google 的批准,然后以这种方式分发他们的应用程序。
这里有一些实际的为什么 Android 电池供电的设备,或任何设备,可能存在电池寿命问题:
使 CPU、屏幕或数据连接保持唤醒状态的应用程序。特别是 LTE 等 4G 芯片组在通电时会消耗大量电量,因此如果您有后台程序不断唤醒 LTE 芯片以传输几千字节的数据,这将很快耗尽您的电池电量。除非您将亮度调到最低,否则现代智能手机和平板电脑的屏幕也非常耗电。
设备上必须安装的“臃肿软件”,无法卸载。一些不道德的运营商要求您运行臃肿软件,这些软件会占用 CPU 周期并保持数据连接处于唤醒状态。这可能是由于臃肿软件的软件开发人员能力不足,也可能是故意监控您在智能手机上的活动并将其发送到远程服务器进行数据挖掘,这会消耗大量电池电量。
最后,我不同意你对 Android 电池寿命问题比其他移动平台更严重的评价。某些手机和设备确实可能存在电池寿命问题,要么是由于电池容量相对于硬件的能耗;要么是由于电源设置优化不佳(由用户、运营商或制造商选择);要么是由于过度膨胀的应用程序使手机中的芯片一直处于唤醒状态。但对于每个存在电池问题的设备示例,我都可以给你一个电池寿命极好的设备的反例。没有简单的方法可以概括为“这是 Dalvik”或“这是 Linux”或“这是 Java”。电源优化是一个复杂的硬件/软件大杂烩,涉及相互竞争的关注点,包括性能、响应能力和用户对电池寿命的期望,每种选择都有利弊。要完全了解设备的电源配置,您必须仔细查看电池本身、所有硬件以及设备上运行的所有软件。
答案2
在这个回答中,我将比较 Android 和 IOS 的性能,因为这两者占据了 80% 以上的市场份额。
Java 应用程序不会消耗更多电量。(http://www.javarants.com/2004/05/04/looks-like-apple-should-switch/) Oracle 的 Java VM 或实际上 Google 的 Dalvik VM 被认为比 IOS 的 Objective-C 更高效。Java 能够在手机上执行代码之前对其进行优化,从而带来更好的性能。Java 库是开源的,因此已被数百名不同的开发人员优化。另一方面,对于 IOS,只有 Apple 开发人员能够更改代码。更少的审核 = 更少的潜在性能。
Android 程序还能够运行本机 C 代码,这可能会比 Object-C(iOS 上唯一支持的语言)更快。
Google 决定使用 Dalvik VM 的原因是为了便于移植。我知道 Android 可以在四种不同的 CPU 架构上正式运行(ARM、MIPS、x86、I.MX)。而其他所有手机操作系统只能使用一种(ARM)。(http://en.wikipedia.org/wiki/Comparison_of_mobile_operating_systems) 因此,将不同类型的 CPU 与 iPhone 进行比较是不公平的。如果 Android 在 iPhone 上运行,那么 Android 将具有可比的卓越性能和电池寿命。
“Java 应用程序是否耗电量更多?”根本不是。
为什么与其他平台/手机相比,Android 手机的电池寿命如此糟糕?
许多 Android 手机的制造成本都低于苹果的 iPhone,但请看价格差异。iPhone 更贵,因为它的电池容量更大(而且 CPU 平均速度较慢)。我的 Android 手机(Google Galaxy Nexus)的电池寿命与 iPhone 4G 相当,但硬件规格更快(1GHz 对 1.2GHZ)。
编辑:Java 可以优化代码,无需程序员的知识。完美,C 代码的运行速度永远比 Java / Objective-C / C# 快;话虽如此,有多少程序员是完美的?在 JVM 级别,Java 和库将永远“更完美”,因为它的开源开发原则。(http://www.infoq.com/news/2012/03/Defects-Open-Source-Commercial)
编辑2:小信息:联想新款 P780 Android 手机 - 通话时间 42 小时,而 iPhone 通话时间 12 小时。
答案3
是的,这确实与功耗增加有关 - 抽象层会造成这种情况。 它还会导致速度降低(同一枚硬币的反面 - 如果某件事的开销更大,则执行时间会更长,因此会占用更多 CPU)。 如果我理解正确的话,这就是开发工具包确实 - 通过编写特定代码来加速特定处理器。
也就是说,对于大多数工作来说,我认为运行虚拟机的“与电源相关”的开销与其他考虑因素相比微不足道——对于大多数程序来说,使用屏幕和无线电将消耗大部分电量。
答案4
是的。
虚拟机“每件事都重复做两次”,而且效率不高。因此,它们处理相同指令时至少要使用“真实机器”两倍的电量。虚拟机的存在会降低速度并消耗更多电量。基本上,iOS 和 Windows 等操作系统会以更快的速度完成所有操作,并且功耗更低。
这意味着屏幕转换、页面加载、导航等方面的真正差异。目前,我正在比较 Android (VM) 和 Windows Phone,即使处理器速度较慢(1GHz vs 1.6GHz),Windows 在执行相同类型的任务时也明显优于 Android。
然而,最让人关注的是,当他们安装一个应用程序时,电池突然消耗得更快。这并不是虚拟机的错,而是一个占用大量资源的应用程序。
虚拟机操作系统的全部原因,即可移植性,并不是基于操作系统的好理由。你看到有人购买他们最喜欢的架构的手机,并使用 Android,因为它的便携性吗?你看到有人放弃更高的性能和可靠性,将 Android 放在非 Android 手机上吗?人们会购买 Android 手机、Windows Phone 或 iPhone 等。为了便携性而牺牲低成本设备的性能是不切实际的。这是一个好主意,但后来失败了。