androidjvm
⑴ Android java虚拟机和sun java虚拟机区别
(1) Dalvik VM和JVM 的第一个区别是 Dalvik VM是基于寄存器的架构(reg based),而JVM是栈机(stack based)。reg based VM的好处是可以做到更好的提前优化(ahead-of-time optimization)。 另外reg based的VM执行起来更快,但是代价是更大的代码长度。
(2) 另外一个区别是Dalvik可以允许多个instance 运行,也就是说每一个Android 的App是独立跑在一个VM中.这样做的好处是一个App crash只会影响到自身的VM,不会影响到其他。 Dalvik的设计是每一个Dalvik的VM都是Linux下面的一个进程。那么这就需要高效的IPC。另外每一个VM是单独运行的好处还有可以动态active/deactive自己的VM而不会影响到其他VM
(3) 接下来就是关于版权之类争论。(可以参看下面文章)
既然reg based VM有那么多好处,为什么之前设计JAVA的人没有采用reg based而是采用stack based的呢? 原来stack based的VM也有其优点,就是它不对host平台的reg数量做假设,有利于移植到不同的平台。而Dalvik则不关心这些,因为它本来就是为ARM这样的多reg平台设计的。另外Dalvik被移植到x86也说明,即使是x86这种reg很少的平台,reg based的VM也是没有问题的。
下面着重说下DVM的优势:(部分文字我加黑以突出)
1、在编译时提前优化代码而不是等到运行时
2、 虚拟机很小,使用的空间也小;被设计来满足可高效运行多种虚拟机实例。
3、常量池已被修改为只使用32位的索引,以 简化解释器
JVM 的字节码主要是零地址形式的,概念上说JVM是基于栈的架构。Google Android平台上的应用程序的主要开发语言是Java,通过其中的Dalvik VM来运行Java程序。为了能正确实现语义,Dalvik VM的许多设计都考虑到与JVM的兼容性;但它却采用了基于寄存器的架构,其字节码主要是二地址/三地址的混合形式。
基于栈与基于寄存器的 架构,谁更快?现在实际的处理器,大多都是基于寄存器的架构,从侧面反映出基于寄存器比基于栈的架构更与实际的处理器接近。但对于VM来说,源架构的求值 栈或者寄存器都可能是用实际机器的内存来模拟的,所以性能特性与实际硬件又有不同。一般认为基于寄存器架构的Dalvik VM比基于栈架构JVM执行效率更高,原因是:虽然零地址指令更紧凑,但完成操作需要更多的load/store指令,也意味着更多的指令分派 (instruction dispatch)次数与内存访问次数;访问内存是执行速度的一个重要瓶颈,二地址或三地址指令虽然每条指令占的空间较多,但总体来说可以用更少的指令完 成操作,指令分派与内存访问次数都较少。
我们从下面的截图可以明了的看到与同一段Java代码对应的Java bytecode 与Dalvid bytecode的比较:
JVM其核心目的,是为了构建一个真正跨OS平台,跨指令集的程序运行环境(VM)。DVM的目的是为了将android OS的本地资源和环境,以一种统一的界面提供给应用程序开发。严格来说,DVM不是真正的VM,它只是开发的时候提供了VM的环境,并不是在运行的时候提供真正的VM容器。这也是为什么JVM必须设计成stack-based的原因。
JVM:所有的jar程序,其运行环境完全是由JVM来提供,包括运行时,各类资源的调度,而JVM的架构,其设计为一个JVM里面可以运行多个java程序,JVM就像一个真正的“机器”,可以跑着多个程序。如果去看看一些企业级的JVM(例如tom cat,WAS),从OS的进程管理中,一般你只能看见一个JVM的进程(当然,你也可以起多个JVM,但JVM架构就是OS-JVM-APP的3层运行时模式),而看不见JVM里面运行的程序,而一个JVM里,可以跑多个java app。简单得说,JVM完全屏蔽了应用程序和OS之间的联系,而改用JVM充当了中间层,这也是一个真正跨平台运行时VM必须要做到的。只要是相同的JDK,JVM为所有在其中运行的程序,提供了完全一致的运行环境,而不论你是什么样的底层OS和硬件条件。因此这也是我在其他一篇答案中提到,JVM的特点是取底层OS和硬件环境的交集,从而保障这种一致性。而所有应用程序和底层资源的互动,一定是依赖JVM的传递和转换来实现。JVM真正实现了一个OS对应用程序运行时管理的所有功能。从开发环境角度和运行时角度,都是完全一致的真正VM
DVM:而DVM的特点在于使用了Zygote,Zygote有几个非常有意思的特点。
一是Zygote采用预加载,由其首先判定安装的APK的需要以及相互依存树,以及OS及硬件环境的特点,在每次启动的时候进行预加载(现在你明白为什么android的app在应用管理里你能轻易查到它都调用了那些关键性的本地资源的原因了吧?),这就意味着,你安装的应用越多,Zygote的加载就越慢,一般来说你的手机启动就会越慢。另外来说,在不同的硬件环境里(例如有无GPS芯片)Zygote初始化的实例是不同的。也就是说,zygote并不提供一个统一的运行环境,具有更好的弹性,这种机制意味着DVM可以取底层资源的合集来提供上层应用使用,差别只是在程序安装或者启动的过程中,DVM可以提示程序需求资源,本地环境可能未能满足而导致无法运行。DVM的Zygote并不是提供一个运行时容器,它提供的只是一个用于共享的进程,所有的应用程序运行,都是独立的,OS级别的进程,直接受到OS层面的资源控制以及调度的影响,只是他们共享Zygote说预加载的类而已。这也就是我为什么说,DVM就像是给每个应用程序在底层加了个套子,而不是提供了一个真正的运行时的VM。也就是说,DVM在开发环境中说提供的VM平台,和运行时的环境是很有可能不一致的。开发环境中提供的VM平台,是一个各种运行时可能环境的合集。
从这点上来说,一般我们认为,JVM中的JAVA程序的崩溃,最多导致JVM的崩溃,而不会导致OS崩溃,但是apk的崩溃,可以直接导致OS崩溃,android手机会因为应用程序死机,大家应该是很常见了。但是大家一般是不会看到java程序导致死机吧?因为运行时中间隔着一个JVM。(当然,其实还是有些小门道可以用java程序让OS崩溃,因为这个,我和某些JAVA大拿打赌赢过饭局,呵呵,不过这是其他话题,不在这里展开了)
除此之外,在JVM的机制中,不同的程序,打包以后,他们都是在运行层级真正独立的程序(指程序应用他们相互之间的关系,而不是和JVM的关系),即便他们在包里使用了同样的类,运行时都是单独加载,单独运行的(及加载多遍)。
DVM这种预加载-共享的机制,使得不同应用之间,在运行时,是共享相同的类的,一般来说,在系统资源消耗方面,拥有更高的效率。
最后,补充一点,byte code并不意味着就是解释执行,也能是加载编译,安装编译,预编译等等。实际上,不同的byte code的程序,不同的技术,不同的具体语言,其真正执行的情况是挺复杂,难以一概而论的,好多都是混合技术的案例,从我对odex的技术来看,就是个典型案例。
⑵ Android应用是运行在JVM上面的吗WP7应用是否运行在CLR之上
Android里的语言VM是Dalvik VM。它单独的看不是一个JVM(但可以看作JVM的衍生物),而如果结合上dx一起看的话,dx + Dalvik可以看作一个JVM实现——因为dx的输入是Java Class文件,而Dalvik VM的设计大部分有考虑到与JVM规范的兼容。
Windows Phone 7上的.NET是.NET Compact Framework而不是与桌面版直接兼容的.NET。就像Java ME跟Java SE有所不同一般。.NET Compact Framework里也有一个CLR实现,我不太清楚它跟桌面版CLR的关系。
Windows Phone 8上的.NET Framework使用的CLR据说叫做PhoneCLR,是CoreCLR的一个变种,与Silverlight用的CoreCLR应该有血缘关系。根据公开的资料看,CoreCLR是.NET Core的CLR,应该是桌面Windows上的CLR Workstation版的精简、可移植版。其大部分源码应该与桌面CLR共通。这跟Java SE Embedded里的HotSpot VM跟Java SE的HotSpot VM的关系类似:共用大部分代码,前者是后者的精简版。
作者:RednaxelaFX
⑶ Android中Dalvik和JVM的区别是什么
按照android官方的说法,android是用java代码编写的,运行在Dalvik虚拟机;
在手机上运行的每各android程序,包含一个android运行时、Dalvik虚拟机和android的核心库。
所以可以这样理解,Dalvik是google自己实现的一个jvm(jvm不只sun有,ibm也自己实现了,据我了解,也就是jvm可以自行实现);
这里的关键就是,你在使用android编写程序的时候,使用的java.lang、java.util、java.io等java的核心包,应该是google的核心类库来实现的这些功能,既然google官方说了“android是用java代码编写的”,这就代表这些类和java中的一样,也就是google按java的规范来实现的他们。而像android.view这样的包只在android中才有,但也是由google的核心类库来实现的。也就是google的核心类库实现了java的基础类同时实现了android的类;这才是问题的关键。至于Dalvik把他理解为为手机设备优化的jvm就可以了。
⑷ android 为什么 native代码的内存 不收jvm控制
jvm内存模型:Java代码是运行在Java虚拟机之上的,由Java虚拟机通过解释执行(解释器)或编译执行(即时编译器)来完成,故Java内存模型,也就是指Java虚拟机的运行时内存模型。 运行时内存模型,分为线程私有和共享数据区两大类,其中线程私有的数据区包含程序计数器、虚拟机栈、本地方法区,所有线程共享的数据区包含Java堆、方法区,在方法区内有一个常量池。java运行时的内存模型图,如下: 从图中,可知内存分为线程私有和共享两大类: (1)线程私有区,包含以下3类: 程序计数器,记录正在执行的虚拟机字节码的地址; 虚拟机栈:方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧; 本地方法栈:虚拟机的Native方法执行的内存区; (2)线程共享区,包含以下2类 Java堆:对象分配内存的区域; 方法区:存放类信息、常量、静态变量、编译器编译后的代码等数据; 常量池:存放编译器生成的各种字面量和符号引用,是方法区的一部分。 楼主提到的Java栈,一般而言是指图中的虚拟机栈,在代码中的方法调用过程中,往往需要从一个方法跳转到另一个方法,执行完再返回,那么在跳转之前需要在当前方法的基本信息压入栈中保存再跳转。 三、关于寄存器的问题 对于java最常用的虚拟机,sun公司提供的hotspot虚拟机,是基于栈的虚拟机;而对于android的虚拟机,则采用google提供的dalvik,art两种虚拟机,在android 5.0以后便默认采用art虚拟机,这是基于寄存器的虚拟机。 楼主问的是jvm(即java vm),这是基于栈的虚拟机。那么关于虚拟机栈,这块内存的内容,我们再进一步详细分析,如下图: 可以看到,在虚拟机栈有一帧帧的 栈帧组成,而栈帧包含局部变量表,操作栈等子项,那么线程在运行的时候,代码在运行时,是通过程序计数器不断执行下一条指令。真正指令运算等操作时通过控制操作栈的操作数入栈和出栈,将操作数在局部变量表和操作栈之间转移。
⑸ 运行Android Studio 提示说"no jvm installation found"怎么办
先找到jdk的安装路径(我的是C:Program FilesJavajdk1.7.0_45)然后是右键我的电脑
点高级系统设置,再点环境变量。看一下自己的系统变量,有的话就编辑,没有的话就新建一个。然后是变量名 JAVA_HOME 变量值就是上面的路径,如C:Program FilesJavajdk1.7.0_45然后就OK了。
⑹ android jni的内存是jvm的内存吗
修改 tomcat 的内存方式: 修改 catalina.bat 在 set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% 这行下面前面加上 JAVA_OPTS='-Xms512m -Xmx1024m' JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=64M -XX:MaxPermSize=256m" 其中 JAVA_OPTS='-Xms512m -Xmx1024m' 是设置Tomcat使用的内存的大小. -XX:PermSize=64M -XX:MaxPermSize=256m 指定类空间(用于加载类)的内存大小 扩大jvm的方法这个说法太泛,其实是在运行jvm的时候指定的,如果你运行的是 tomcat 就是改 catalina.bat 如果你运行的是eclipse 就是修改 eclipse.ini 所以jvm的内存大小怎么修改是看你运行的具体程序的,不通程序有不同的改法
⑺ android studio提示没有JVM
android Studio没有找到与之匹配的JAVA版本的JVM。所以即便安装了java也不能通过,解决的办法有2种
方法1:修改android Studio 配置文件
在应用程序中找到Android Studio.app ->右击显示包内容,在目录下找到 info.plist 并用任意文本编辑器打开 -> 找到 JVMVersion 并将 <string>1.6*</string>中的版本号改为你系统JDK的版本号。 注意:Android Studio只支持jdk1.6及以上版本。
1:拖动android studio 到application在应用程序中找到Android Studio.app ->右击显示包内容
⑻ 安卓手机的所有应用程序是否都依赖于JVM不依赖JVM的程序在安卓系统能否运行
安卓就是java虚拟机,不依赖jvm的程序怎么编译出来!
⑼ Android studio JVM的环境变量要怎么设置
是不是,版本不对。
android studio的bin目录下,你用32打开,还是64位打开的?
⑽ Android Studio的JVM内存不足问题怎么解决
找到Eclipse安装文件下的eclipse.ini配置文件
通常里面都是写的-vmargs-Xms40m-Xmx256m
-vmargs:说明后面是VM的参数
-Xms40m:虚拟机占用系统的最小内存
Xmx256m:虚拟机占用系统的最大内存
-XX:PermSize:最小堆大小.一般报内存不足时,都是说这个太小,堆空间剩余小于5%就会警告,建议把这个稍微设大一点,不过要视自己机器内存大小来设置-XX:PermSize:最大堆大小.这个也适当大些,另外把里面的参数改为:
-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=128M
-XX:MaxPermSize=256M
1、设置Eclipse内存使用情况
修改eclipse根目录下的eclipse.ini文件
-vmargs //虚拟机设置
-Xms40m
-Xmx256m
-XX:PermSize=128M //非堆内存设置
-XX:MaxPermSize=256M
2、JVM内存设置
打开eclipse window-preferences-Java -Installed JREs -Edit -Default VM Arguments 在VM自变量中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m3, Tomcat内存设置
打开Tomcat根目录下的bin文件夹,编辑catalina.bat 修改为:set JAVA_OPTS= -Xms256m -Xmx512m下面是这几个设置的一些背景知识:
1 堆(Heap)和非堆(Non- heap)内存
按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给 自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。 2 堆内存分配
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存 小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、 -Xmx相等以避免在每次GC 后调整堆的大小。
3、非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
4、JVM内存限制(最大值)
首先JVM内存首先受限于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然 可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统 下为 2G-3G),而64bit以上的处理器就不会有限制了