我的应用程序在Linux上作为后台进程运行.它目前在终端窗口的命令行中启动.
最近一个用户正在执行该应用程序一段时间,它神秘地死了.文本:
杀害
在终端上.这发生了两次.我问是否有人在不同的终端使用kill命令来杀死进程?没有.
在什么条件下Linux会决定杀死我的进程?我相信shell显示"已杀死",因为该进程在收到kill(9)信号后死亡.如果Linux发送了kill信号,系统日志中是否会有消息说明它被杀的原因?
我使用/ proc/meminfo和解析命令响应.但是它的结果显示:
MemTotal:94348 kB MemFree:5784 kB
手段.它显示只有5MB的可用内存.Android手机有可能吗?我的手机上只安装了5-6个应用程序,没有其他任务正在运行.但仍然这个命令显示可用内存很少.
有人可以澄清一下吗?或者有没有其他方法在Android中获取内存?
对于我的10,000点,我决定用这个很酷的网站来点缀一些东西:一种在本机内存上缓存位图的机制.
Android设备的每个应用程序的内存量非常有限 - 堆的范围从16MB到128MB,具体取决于各种参数.
如果您通过此限制,则会获得OOM,当您使用位图时,这可能会发生多次.
很多时候,应用程序可能需要克服这些限制,对巨大的位图执行繁重的操作,或者只是存储它们以供以后使用,并且您需要
我想出的是一个简单的java类,它可以使事情变得更容易.
它使用JNI来存储位图数据,并能够在需要时恢复它.
为了支持该类的多个实例,我必须使用我发现的技巧(这里).
数据仍然存储在RAM中,因此如果设备没有足够的RAM,应用程序可能会被杀死.
记得尽快释放记忆.它不仅可以避免内存泄漏,而且还可以避免在您的应用程序到达后台时首先被系统优先处理.
如果您不想忘记释放内存,可以在每次还原位图时释放它,或者使类实现Closable.
作为一种安全措施,我已经使它在finalize()方法中自动释放其本机内存,但不要让它负责这项工作.风险太大了.当这样的事情发生时,我也写了它写入日志.
它的工作方式是将整个数据复制到JNI对象中,为了还原,它从头开始创建位图并将数据放入其中.
正在使用和恢复的位图采用ARGB_8888格式.当然,您可以将其更改为您想要的任何内容,只是不要忘记更改代码...
大位图可能需要一些时间来存储和恢复,因此在后台线程上执行它可能是明智的.
这不是一个完整的OOM解决方案,但它可能有所帮助.例如,您可以将它与您自己的LruCache结合使用,同时避免将堆内存用于缓存本身.
代码仅用于存储和恢复.如果您需要执行某些操作,则需要进行一些研究.openCV可能就是答案,但是如果你想要执行一些基本的东西,你可以自己实现它们(这里是使用JNI旋转大图像的例子).如果你知道其他选择,请在这里告诉我.
希望这对某些人有用.请写下你的意见.
此外,如果您发现代码有任何问题或建议填补,请告知我们.
如果您希望在JNI端执行更多操作,您可以使用我所做的这篇文章.它基于我在这里编写的代码,但允许您进行更多操作,您可以轻松添加更多自己的代码.
根据Android参考文档Bitmap.recycle():
释放与此位图关联的本机对象,并清除对像素数据的引用.这不会同步释放像素数据; 如果没有其他引用,它只是允许它被垃圾收集.位图标记为"死",这意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容.此操作无法撤消,因此只有在您确定位图没有进一步用途时才应调用此操作.这是一个高级调用,通常不需要调用,因为正常的GC进程将在没有更多对此位图的引用时释放此内存.
但是,我读过的很多书都建议通过调用Bitmap.recycle()来释放内存,确保不再需要它.
这让我很困惑:使用后是否需要打电话Bitmap.recycle()?
我已经决定,由于位图会占用大量内存,而这些内存很容易导致内存不足错误,因此我会对C/C++代码进行大量内存消耗.
即使一切似乎都没有任何错误,输出图像也不是原始的旋转.事实上,它完全毁了它.
旋转应该是逆时针方向,90度.

所以你可以看到,不仅颜色变得怪异,而且尺寸与我设定的尺寸不符.这里真的很奇怪.
也许我没有正确读取/放置数据?
当然这只是一个例子.代码应该可以在任何位图上正常工作,只要设备有足够的内存来容纳它.另外,我可能想在位图上执行其他操作而不是旋转它.
Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniTest
LOCAL_SRC_FILES := JniTest.cpp
LOCAL_LDLIBS := -llog
LOCAL_LDFLAGS += -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
APP_OPTIM := debug
LOCAL_CFLAGS := -g
Run Code Online (Sandbox Code Playgroud)
cpp文件:
#include <jni.h>
#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <android/bitmap.h>
#include <cstring>
#include <unistd.h>
#define LOG_TAG "DEBUG"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
extern "C"
{
JNIEXPORT jobject JNICALL Java_com_example_jnitest_MainActivity_rotateBitmapCcw90(JNIEnv * env, jobject obj, jobject …Run Code Online (Sandbox Code Playgroud) java-native-interface android bitmap image-rotation android-ndk
该应用程序的某些文件只能存储在res/raw或assets文件夹中.
每个文件夹的工作方式与另一个文件夹的工作方式非常相似.res/raw文件夹允许更容易地访问文件,具有资源文件的所有其他好处,而资产文件夹允许访问它们,无论文件名和结构如何(包括文件夹和子文件夹).
加载文件的主要思想对于它们来说大致相同.您可以选择易用性,具体取决于您的需求.
我记得很久以前,我发现这两个文件夹都有一些特殊的行为:
assets文件夹中的每个文件夹都有最大数量的文件.我认为它大概是500,但不确定.我很久以前就注意到了这种行为,
有人说资产文件夹中的文件具有文件的最大大小(例如此处).我从未见过这样的限制.当时甚至不在Android 2.3上.
有人说(这里的例子),即使在今天(例如这里)仍然相信,如果从res/raw加载文件,它可能比从assets文件夹中获取文件需要更多的内存.
对于#1,在我工作的项目之后,我从来没有使用过更多的文件,在我工作的时候,我们只是将文件拆分成更多的文件夹.
对于#2,正如我写的那样,我从来没有注意到它.我使用了更大的文件大小.
对于#3,我尝试制作一个示例项目,比较两种方法之间的内存使用情况.我没有注意到两种方法之间的任何差异(内存使用或加载时间).特别是不是主要的.可悲的是,我只有一个设备(Nexus 5x),它有一个新的Android版本(8.1).可能是从特定的Android版本开始,两种方法之间没有区别.这样做的另一个原因是,由于GC,测量Java上的内存使用量更难,而且我已经注意到在Android 8.x上,内存的工作方式与之前有所不同(在此处写).
我试着读一下上面的差异和限制,但我发现的都是非常古老的文章,所以我认为事情可能从此改变过.
实际上这只是一个问题,但我想分开它,以防答案很复杂:
使用res/raw和assets文件夹之间是否存在任何主要或唯一的限制或差异?
从assets文件夹中读取文件(通过从中创建输入流)确实比使用res/raw占用更少的内存吗?即使是现在,即使是最受赞赏的开发商之一(这里)也决定选择它?
上述限制是否存在于特定的Android版本中,然后它们在没有任何限制方面变得相同(当然文件命名为res/raw,但这只是它的工作方式)?
如果是这样,他们从哪个Android版本开始工作呢?
VM堆的大小不能超过16mb,24mb,32mb,具体取决于手机.但是本机堆的最大大小是多少?当应用程序处于前台时,可以为应用程序分配多少本机内存.
谢谢.
Android P使用ImageDecoder类提供了一个用于加载图像的新API .
并非被记录关于这个类,所以我只是好奇它的用法,我是否应该考虑尽可能使用它,而不是滑行库,例如,其中谷歌本身建议使用:
对于大多数情况,我们建议您使用Glide库来获取,解码和显示应用中的位图.Glide在处理与在Android上使用位图和其他图像相关的这些和其他任务时,大部分复杂性都是抽象的.有关使用和下载Glide的信息,请访问GitHub上的Glide存储库.
我发现了一些关于它的文章,提供了它可以做什么以及如何使用它的线索:
但是,根据我的测试,与Movie类相比,加载GIF动画更糟糕的是使用此API(占用更多内存,使用大约相同的CPU),而Movie类本身比第三方库(如android-gif-drawable)更糟糕.我测试的是一个相当长的GIF动画.在第三方库上花了大约59MB.使用Movie类需要大约168MB,使用新的ImageDecoder API需要200-300MB ...
简而言之,我发现这个API的原因是:
android animated-gif android-bitmap imagedecoder android-9.0-pie
android ×7
bitmap ×3
android-ndk ×1
animated-gif ×1
caching ×1
imagedecoder ×1
kill ×1
linux ×1
memory ×1
memory-leaks ×1
native ×1
process ×1
recycle ×1
signals ×1