http://oxygenplan.blogspot.sg/2011/02/androidjvmbitmap-buffer.html
在Android裡面,當app嘗試索取memory時,此時若process的memory使用量超過上限時,JVM會丟出out of memory的exception,我們可以在Heap.c裡面的dvmMalloc(size_t size, int flags)找到.
void* dvmMalloc(size_t size, int flags) {
...
ptr = tryMalloc(size);
...
if (ptr != NULL) {
...
} else {
...
LOGE("Out of memory: Heap Size=%dKB, Allocated=%dKB, Bitmap Size=%dKB, Limit=%dKB",
dvmHeapSourceGetValue(HS_ALLOWED_FOOTPRINT, NULL, 0)/1024,
dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, NULL, 0)/1024,
dvmHeapSourceGetValue(HS_EXTERNAL_BYTES_ALLOCATED, NULL, 0)/1024,
gDvm.heapSizeMax / 1024);
...
}
...
}
但是本篇中,我們只關注於Bitmap裡面pixel buffer的使用量.從source code中可發現,VM是監控HS_EXTERNAL_BYTES_ALLOCATED的使用量,來控管Bitmap size.
我們寫一段簡單的sample code, 看看HS_EXTERNAL_BYTES_ALLOCATED的memory使用量的變化.
public class Foo {
public void monitorBitmap() {
Bitmap src = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
...
src.recycle();
}
}
在這個sample code的monitorBitmap()中只做了兩件事情:
1. new一個Bitmap,
2. 回收它(recycle()).
首先,trace create Bitmap object 的過程,
1. createBitmap(int width, int height, Config config); [Bitmap.java]
2. nativeCreate(int[] colors, int offset, int stride, int width, int height, int nativeConfig, boolean mutable); [Bitmap.java]
---JNI------------------------------------------------------
3. Bitmap_creator(JNIEnv* env, jobject, jintArray jColors, int offset, int stride, int width, int height, SkBitmap::Config config, jboolean isMutable); [Bitmap.cpp]
4. GraphicsJNI::setJavaPixelRef(env, &bitmap, NULL, true); [Graphics.cpp]
5.1. JNIEnv::CallBooleanMethod(gVMRuntime_singleton, gVMRuntime_trackExternalAllocationMethodID, jsize); [Graphics.cpp]
5.2. void* addr = sk_malloc_flags(size, 0); [Graphics.cpp]
5.3. SkPixelRef* pr = new AndroidPixelRef(env, addr, size, ctable, reportSizeToVM); [Graphics.cpp]
5.4. bitmap->setPixelRef(pr)->unref(); [Graphics.cpp]
在步驟5.1., JVM紀錄Bitmap的size,並追蹤它. 5.2.,5.3. malloc pixel buffer同時放入SkPixelRef object中以方便控管. SkPixelRef繼承SkRefCnt,因此使用了reference count的技巧,可以偵測有多少個object參考到它. 5.4. 將SkPixelRef放入SkBitmap, 同時將先前Bitmap object內部所持有的SkPixelRef object unref().
最後,我們來看當Bitmap object被recycle()時,做了哪些處理:
1. recycle(); [Bitmap.java]
2. nativeRecycle(int nativeBitmap); [Bitmap.java]
---JNI------------------------------------------------------
3. Bitmap_recycle(JNIEnv* env, jobject, SkBitmap* bitmap); [Bitmap.cpp]
4. SkBitmap::setPixels(NULL, NULL); [SkBitmap.cpp]
5. SkBitmap::freePixels(); [SkBitmap.cpp]
6. AndroidPixelRef::unref(); [Graphics.cpp]
7. AndroidPixelRef::~AndroidPixelRef(); [Graphics.cpp]
8. JNIEnv::CallVoidMethod(gVMRuntime_singleton, gVMRuntime_trackExternalFreeMethodID, jsize); [Graphics.cpp]
在步驟8, JVM移除先前所記載的pixel buffer size的紀錄.
由上面的範例中,我們可以得知JVM是如何記錄與追蹤Bitmap size的大小.
Dalvik:
进行数据统计,然后调用GC。其实还是全部靠Bitmap自己管理。
分享到:
相关推荐
代码如下:failed to create jvm error code -4 这一般应是内存不够用所致,解决方法参考如下。 打开 Android Studio 安装目录下的bin目录,查找并打开文件 studio.exe.vmoptions,修改代码: 代码如下:-Xmx512m 为...
SJK exploits standard diagnostic interfaces of JVM (such as JMX, JVM attach and perf counters) and add some more logic on top to be useful for common troubleshooting case. SJK is also can be used as ...
PufferDB是一款专为Android和JVM平台设计的键值存储系统,它巧妙地结合了Google的Protocol Buffers(Protobuf)和Kotlin的Coroutines技术,旨在提供高效、可靠的数据存储解决方案。这款库的目标是为开发者提供一个轻...
> JVM沙箱容器,一种JVM的非侵入式运行期AOP解决方案 > Real - time non-invasive AOP framework container based on JVM 目标群体 BTRACE好强大,也曾技痒想做一个更便捷、更适合自己的问题定位工具,既可支持线上...
"JVM设置Young Gen大小"这个话题涉及到的是如何调整Java堆内存中年轻代(Young Generation)的大小,以优化应用程序的性能。年轻代是新生对象的存放区域,它的大小直接影响垃圾收集(Garbage Collection, GC)的频率...
在 Java 和 Kotlin 等 JVM 语言中,协程库如 Kotlin 的 `kotlinx.coroutines` 提供了一种轻量级的异步编程解决方案,可以有效解决 Android 和 JVM 平台上的回调地狱问题。在 PufferDB 中,协程被用来优化 I/O 操作,...
在IT领域,特别是Web应用服务器管理中,正确配置Java虚拟机(JVM)的内存大小对于确保应用程序的稳定性和性能至关重要。本文将详细探讨如何在Tomcat服务器上配置JVM内存,包括其背景、配置方法以及最佳实践。 #### ...
本文将深入探讨如何在Java中获取JVM内存大小,包括堆内存的总量、最大值以及剩余空间,并解析给定代码片段中的关键概念。 ### JVM内存模型 在讨论如何获取JVM内存大小之前,首先需要理解JVM的内存布局。JVM内存...
Katana是一个专为Android和Kotlin(JVM)平台设计的轻量级、低依赖性的依赖注入库。它借鉴了服务定位器模式,为开发者提供了一种简洁的方式来管理对象之间的依赖关系,从而简化代码结构,提高可测试性和可维护性。 ...
根据操作系统限制,我们可能无法充分利用所有物理内存,因为32位系统通常限制JVM的最大堆大小在1.5GB到2GB之间。为了达到最优性能,我们可以按照以下步骤配置JVM参数: 1. **设置堆大小**:考虑到32位系统的限制,...
在Android开发中,`Bitmap`对象是用于表示图像的主要类之一。然而,在处理大量或高分辨率图像时,不当的`Bitmap`管理常常会导致内存溢出问题,这严重影响了应用程序的性能和用户体验。接下来,我们将深入探讨如何...
在现代软件开发中,Java虚拟机(JVM)作为执行Java字节码的核心组件,其性能直接影响到Java应用的运行效率与稳定性。特别是在大数据处理场景下,合理设置JVM内存参数显得尤为重要。本文将深入探讨JVM内存管理的基础...
标题中提到了JVM原理、JVM调优、JVM内存模型和JAVA并发,这些都是Java虚拟机(JVM)相关的核心概念。JVM是运行Java字节码的虚拟计算机,为Java提供了一个跨平台的环境,确保Java程序可以在不同的操作系统上运行而...
在设置 Tomcat 的 JVM 虚拟机大小中,需要了解 JVM 的基本概念和 Tomcat 的配置文件。下面是相关的知识点: 1. JVM 的基本概念:JVM(Java Virtual Machine)是 Java 程序的运行环境,负责将 Java 字节码转换为机器...
在Eclipse这样的集成开发环境中,对Java虚拟机(JVM)进行设置是非常关键的,因为它直接影响到应用程序的性能和稳定性。Eclipse中的JVM内存设置涉及到多个参数,这些参数用于控制JVM如何分配和管理内存资源。以下是...
- **JVM参数设置**:通过设置-Xms, -Xmx控制堆内存大小,-Xss设置栈内存大小,-XX:NewRatio调整新生代与老年代比例等。 - **监控与诊断**:使用JVisualVM、JConsole等工具监控JVM状态,找出内存泄漏和性能瓶颈。 ...
JVM(Java Virtual Machine,Java虚拟机)是运行所有Java程序的假想计算机,是Java程序的运行环境,负责执行指令、管理数据、内存、寄存器等,是实现Java跨平台特性的关键部分。JVM指令手册详细记录了JVM的所有操作...
开发版本的快照可在Sonatype 的snapshots存储库中找到。 改造至少需要 Java 8+ 或 Android API 21+。 R8 / ProGuard 如果您使用 R8,则会自动包含收缩和混淆规则。 ProGuard 用户必须手动添加Retrofit2.pro中的...
### 如何设置Tomcat的JVM虚拟机内存大小 在部署和运行基于Java的应用程序时,经常需要调整Tomcat服务器的JVM(Java虚拟机)内存配置以优化性能。合理设置JVM内存对于确保应用程序稳定运行至关重要。本文将详细介绍...
Uber JVM Profiler Uber JVM Profiler provides a Java Agent to collect various metrics and stacktraces for Hadoop/Spark JVM processes in a distributed way, for example, CPU/Memory/IO metrics. Uber ...