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以上的處理器就不會有限制了