淺談 maxMemory , totalMemory , freeMemory 和 OOM 與 native Heap

作者:林冠宏 / 指尖下的幽靈

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8

博客:http://www.cnblogs.com/linguanh/

GitHub : https://github.com/af913337456/

騰訊云專欄: https://cloud.tencent.com/developer/user/1148436/activities

回答內存管理類面試問題可以說出下面這些內容,加分。


前言: 站在巨人的肩膀上,總結此文。

目錄:

  • Java runtime 三個計算內存函數
  • OOM 的說法,為什么大型游戲能申請那么多內存?
  • 如何繞過dalvikvm heap size的限制 ?
  • Bitmap分配在native heap還是dalvik heap上?

1,Java runtime 三個計算內存函數:

maxMemory
獲取當前 APP 最大能夠申請的內存,在 Java Heap 部分。

totalMemory
獲取當前 APP 已經從系統拿到的內存,包含使用上了的和沒有用上的,因為一般申請會申請多一部分,它總是慢慢按需要從系統拿取。

freeMemory
獲取當前 APP 拿到的內存中,還沒用上的,即是可以被 gc 回收的。

計算此刻 APP 在 Java Heap 層次已經使用了的內存 usedMemory


usedMemory = totalMemory - freeMemory

2,OOM 的說法,為什么大型游戲能申請那么多內存?

在不同的 Android 系統版本中,OOM 的判斷是不一樣的。

  • 通俗來說,OOM 是當前進程共申請的內存綜和超過一個限制,而被拋出。

  • 專業來說,Android為每個進程設置Dalvik Heap Size閾值,這個閾值在不同的設備上會因為RAM大小不同而各有差異。如果APP想要分配的內存超過這個閾值,就會發生OOM。

  • Android 3.x以前,Bitmap分配在Native heap中,而在3.x之后,Bitmap分配在Dalvik或ART的Java heap中。

  • Android 2.x系統,當dalvik allocated + native allocated + 新分配的大小 >= dalvik heap 最大值時候就會發生OOM,也就是說在2.x系統中,考慮native heap對每個進程的內存限制。

  • Android 3.x系統,廢除了native的計數器,類似bitmap的分配改到dalvik的java heap中申請,只要allocated + 新分配的內存 >= dalvik heap 最大值的時候就會發生OOM(art運行環境的統計規則還是和dalvik保持一致),也就是說在3.x系統中,不考慮native heap對每個進程的內存限制,native heap只會收到本機總內存(包括RAM以及SWAP區或分頁文件)的限制。

這也是為什么有些APP(比如大型游戲)可以超過 Dalvik Heap Size 這個值?那是因為Java內存又分為Java Heap和Native Heap,3.X 后 Native Heap是不受該值約束的。像C/C++的內存都是在Native Heap中分配的。另外Bitmap是在Java Heap中分配的,我們開發過程中經常遇到由Bitmap引起的OOM,這就是一個例子。

3,如何繞過dalvikvm heap size的限制 ?

  • 創建子進程,上面說了,內存分配按進程來。再使用進程通訊

創建一個新的進程,那么我們就可以把一些對象分配到新進程的heap上了,從而達到一個應用程序使用更多的內存的目的,當然,創建子進程會增加系統開銷,而且并不是所有應用程序都適合這樣做,視需求而定。

創建子進程的方法:使用android:process標簽

  • 按不同的系統版本,使用 jni 在native heap上申請空間(推薦使用)

3.X 后的系統 native heap的增長并不受dalvik vm heapsize的限制,只要RAM有剩余空間,程序員可以一直在native heap上申請空間,當然如果 RAM快耗盡,memory killer會殺進程釋放RAM。大家使用一些軟件時,有時候會閃退,就可能是軟件在native層申請了比較多的內存導致的。比如,我就碰到過UC web在瀏覽內容比較多的網頁時閃退,原因就是其native heap增長到比較大的值,占用了大量的RAM,被memory killer殺掉了。

  • 使用顯存(操作系統預留RAM的一部分作為顯存)

使用OpenGL textures等API,texture memory不受dalvik vm heapsize限制,這個我沒有實踐過。再比如Android中的GraphicBufferAllocator申請的內存就是顯存。

4,Bitmap分配在native heap還是dalvik heap上?

上面說了,不同的系統版本不同,那么在 3.X 及其之后,為什么在 java heap 而不是在 native heap 。請看下面源碼。

主要的文件

framework/base/graphic/java/Android/graphics/BitmapFactory.java  
framework/base/core/jni/Android/graphics/BitmapFactory.cpp  
framework/base/core/jni/Android/graphics/Graphics.cpp  

BitmapFactory.java 里面有幾個decode***方法用來創建bitmap,最終都會調用:


private staticnative Bitmap nativeDecodeStream(InputStream is, byte[] storage,Rect padding,Options opts);

nativeDecodeStream()會調用到BitmapFactory.cpp中的deDecode方法,最終會調用到Graphics.cppcreateBitmap方法。

createBitmap方法的實現:

jobjectGraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,  boolisMutable, jbyteArray ninepatch, int density)  
{  SkASSERT(bitmap);  SkASSERT(bitmap->pixelRef());  jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,  static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)),  buffer, isMutable, ninepatch,density);  hasException(env); // For the side effectof logging.  return obj;  
}  

從代碼中可以看到bitmap對象是通過env->NewOject(...)創建的,到這里疑惑就解開了,bitmap對象是虛擬機創建的,JNIEnv的NewOject方法返回的是java對象,并不是native對象,所以它會分配到dalvik heap中。

轉載于:https://www.cnblogs.com/linguanh/p/8496002.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284004.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284004.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284004.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RestTemplate 詳解

在項目中&#xff0c;當我們需要遠程調用一個 HTTP 接口時&#xff0c;我們經常會用到 RestTemplate 這個類。這個類是 Spring 框架提供的一個工具類。Spring 官網對它的介紹如下&#xff1a; RestTemplate: The original Spring REST client with a synchronous, template met…

初識Spark2.0之Spark SQL

內存計算平臺Spark在今年6月份的時候正式發布了spark2.0&#xff0c;相比上一版本的spark1.6版本&#xff0c;在內存優化&#xff0c;數據組織&#xff0c;流計算等方面都做出了較大的改變&#xff0c;同時更加注重基于DataFrame數據組織的MLlib&#xff0c;更加注重機器學習整…

webpack開發Vue配置

一直以來使用webpack都是用的別人的配置&#xff0c;這幾天自己學習了一下。 項目地址&#xff1a;https://github.com/donghaohao... 新建整個工程 npm init安裝依賴&#xff0c;這里我們開發vue項目&#xff0c;npm install vue --save&#xff0c;然后是開發時的依賴npm ins…

ABP詳細教程——模塊類

概述模塊化是ABP vNext的最大亮點&#xff0c;也是ABP vNext框架的核心&#xff0c;而模塊類是ABP vNext框架模塊化的核心要素。這一章節&#xff0c;我就從模塊類的用法、運行機制、源代碼等層面&#xff0c;帶大家詳細了解ABP vNext的模塊類。用法在ABP的約定中&#xff0c;每…

[轉]Eureka工作原理

目錄 Eureka 工作原理 Eureka 核心概念 自我保護機制 Eureka 集群原理 Eurka 工作流程 總結 Eureka 工作原理 上節內容為大家介紹了&#xff0c;注冊中心 Eureka 產品的使用&#xff0c;以及如何利用 Eureka 搭建單臺和集群的注冊中心。這節課我們來繼續學習 Eureka&…

centos7下別名(alias)的特殊用法

版權聲明&#xff1a;轉載請注明出處:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79438200 參考&#xff1a;https://www.cyberciti.biz/faq/bash-bypass-alias-command-on-linux-macos-unix/ 正常情況下&#xff0c;定義過的別名&a…

解決WDCP3環境gbk網站編碼程序亂碼問題

因為默認WDCP V3版本環境編碼格式是UTF-8版本&#xff0c;如果我們程序采用的是GBK編碼肯定都會有亂碼問題。 我們到WDCP后臺&#xff0c;"網站管理"-"PHP設置"&#xff0c;看到上圖所示&#xff0c;準備直接在線編輯PHP.INI文件。 這里我們找到"defa…

重談聯想5G編碼投票事件

此前&#xff0c;司馬南談了聯想好幾個問題&#xff0c;其中最尖銳的要屬國有資產流失&#xff0c;這是聯想管理層無法回避的死穴。不過&#xff0c;司馬南批判聯想5G投票背刺H公司&#xff0c;這基本就是造謠了。當年&#xff0c;媒體把編碼投票炒作的很厲害&#xff0c;抨擊聯…

JStorm2.1.1集群的安裝和使用

為什么80%的碼農都做不了架構師&#xff1f;>>> JStorm2.1.1集群的安裝和使用 Storm是一個免費開源、分布式、高容錯的實時計算系統&#xff0c;而JStorm是阿里巴巴開源的基于Storm采用Java重寫的一套分布式實時流計算框架&#xff0c;在性能和支持的集群規模上做了…

Hystrix 原理

Hystrix是什么&#xff1f; Hystrix是Netflix開源庫&#xff0c;這是一個針對分布式系統的延遲和容錯庫。 Hystrix 供分布式系統使用&#xff0c;提供延遲和容錯功能&#xff0c;隔離遠程系統、訪問和第三方程序庫的訪問點&#xff0c;防止級聯失敗&#xff0c;保證復雜的分布…

「深度」無人機實名制政策特稿|市場看好、資本關注,“反黑飛”正在崛起

從政策和需求來看&#xff0c;“反黑飛”越來越重要&#xff0c;市場也正在不斷崛起。 對于大多數人來說&#xff0c;今天是最適合明目張膽“裝嫩”的六一兒童節。不過&#xff0c;在無人機廠商和無人機玩家的眼里&#xff0c;今天是無人機實名制政策正式實施的日子。 近年來&…

在navicat中新建數據庫

前言&#xff1a; 在本地新建一個名為editor的數據庫&#xff1b; 過程&#xff1a; 1.&#xff1b; 2.選擇&#xff1a;utf8mb4 -- UTF-8 Unicode字符集&#xff0c;原因在于&#xff1a;utf8mb4兼容utf8&#xff0c;且比utf8能表示更多的字符。&#xff0c;而且它支持表情符號…

MASA Stack 第三期社區例會

MASA Blazor 0.5.0發版內容功能Autocomplete&#xff1a;支持通過設置AutoSelectFirst參數開啟自動選擇第一項的功能&#xff0c;支持CacheItems參數&#xff0c;增強使用上下鍵的用戶體驗。BottomNavigation&#xff1a;&#xff1a;一個替代側邊欄的新組件。它主要用于移動應…

MySQL添加用戶、刪除用戶與授權

MySql中添加用戶,新建數據庫,用戶授權,刪除用戶,修改密碼(注意每行后邊都跟個;表示一個命令語句結束): 1.新建用戶 1.1 登錄MYSQL&#xff1a; >mysql -u root -p >密碼 1.2 創建用戶&#xff1a; mysql> insert into mysql.user(Host,User,Password) values("lo…

[轉]高并發架構設計之--「服務降級」、「服務限流」與「服務熔斷」

目錄 服務降級 1 、簡介 2 、使用場景 3 、核心設計 3.1 分布式開關 3.2 自動降級分類 3.3 配置中心 3.4 處理策略 3.5 降級分類 3.6 服務降級要考慮的問題 4 、高級特性 4.1 分級降級 4.2 降級權值 5 、總結與展望 服務限流 一、為什么要做服務限流設計&…

【Linux】【Services】【nfs】nfs安裝與配置

1. 概念 1.1. NFS&#xff1a;Network File System&#xff0c;傳統意義上&#xff0c;文件系統在內核中實現。 1.2. RPC&#xff1a;Remote Procedure Call protocol&#xff0c;遠程過程調用&#xff0c;函數調用&#xff08;遠程主機上的函數&#xff09; 1.3. 端口&#xf…

SpringBoot獲取ApplicationContext

2019獨角獸企業重金招聘Python工程師標準>>> 有兩種方法&#xff1a; 創建Component實現ApplicationContextAware接口&#xff0c;SpringBoot會自動調用這個類的setApplicationConext()方法。鼓勵使用這種方式。SpringApplication.run(MyApplication.class, args)這…

SkiaSharp 之 WPF 自繪 投籃小游戲(案例版)

此案例主要是針對光線投影法碰撞檢測功能的示例&#xff0c;順便做成了一個小游戲&#xff0c;很簡單&#xff0c;但是&#xff0c;效果卻很不錯。投籃小游戲規則&#xff0c;點擊投籃目標點&#xff0c;就會有一個球沿著相關拋物線&#xff0c;然后&#xff0c;判斷是否進入籃…

zuul集成ribbon完成服務通信和負載均衡

目錄 Zuul2服務通信 超時相關 默認超時配置 自定義超時配置 負載均衡 Zuul2服務通信 描述&#xff1a;zuul2通過Ribbon完成客戶端負載均衡以及與服務器群集進行通信。 zuul2的通信是集成Ribbon實現的&#xff0c;在Origin中集成Ribbon基本配置&#xff08;例如IClientCo…

時任上海來伊份互聯網事業群總裁王戈鈞 :傳統企業(線上+線下)移動互聯網改造...

2017年12月22日-23日&#xff0c;第13屆信息化領袖峰會暨2017中國數字化貢獻人物頒獎盛典在上海盛大開幕。本次峰會由上海市經濟和信息化委員會指導&#xff0c;上海市國有資產信息中心、上海市計算機用戶協會、上海市信息服務業行業協會、上海大數據聯盟、上海市高等教育學會支…