Java 确定Android上的可用内存
因此,Android面临的挑战之一是各种设备规格(特别是设备内存) 我已经编写了我的模型对象,以便以延迟加载方式广泛使用JavaJava 确定Android上的可用内存,java,android,memory-management,android-ndk,Java,Android,Memory Management,Android Ndk,因此,Android面临的挑战之一是各种设备规格(特别是设备内存) 我已经编写了我的模型对象,以便以延迟加载方式广泛使用JavaSoftReferences,因此虚拟机可以自由地修剪数据模型中当前未使用的部分,并根据需要重新构建它们 然而,SoftReferences在实践中面临的一个挑战是,它们往往在变为弱引用的几秒钟内被清除,而不是在虚拟机内存不足时才被清除,因此它们在允许模型修剪方面工作得很好,但它们工作得不好,因为这通常意味着内存中没有任何内容。理想情况下,在内存充足的设备上,您可以让用
SoftReferences
,因此虚拟机可以自由地修剪数据模型中当前未使用的部分,并根据需要重新构建它们
然而,SoftReferences
在实践中面临的一个挑战是,它们往往在变为弱引用的几秒钟内被清除,而不是在虚拟机内存不足时才被清除,因此它们在允许模型修剪方面工作得很好,但它们工作得不好,因为这通常意味着内存中没有任何内容。理想情况下,在内存充足的设备上,您可以让用户受益于将对象保留在内存中
因此,通常将SoftReferences
与LRU机制相结合,LRU将硬指针保持在最近引用的对象上。当然,这并不理想,因为它假设您有足够的内存来存储所有这些几乎不被引用的对象
这也使得了解什么是LRU的良好违约成为一个挑战
在一个完美的世界中,Android会使用它的低内存回调作为提示(因此我可能从一个小的LRU开始,周期性地将其提升,直到低内存回调开始发生,然后将其退出,以找到一个设备的良好值),但根据我的经验,这种回调似乎从未与实际的VM内存压力相符
有没有人找到一种合理的方法来检测您的数据模型在特定设备上使用了过多的内存?这是否可行
MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
如果您使用Android NDK:
#包括
大小\u t getTotalSystemMemory()
{
长页面=系统配置(物理页面);
长页面大小=sysconf(\u SC\u页面大小);
返回页面*页面大小;
}
大小\u t getFreeSystemMemory()
{
长页面=sysconf(_SC_AVPHYS_页面);
长页面大小=sysconf(\u SC\u页面大小);
返回页面*页面大小;
}
如果您想确定android中的可用内存,那么您可以检查或进入
透视->ddms
2) 第二件事是您可以使用内存分析器工具检查已使用和未使用的内存,您还可以检查
内存可用性。以下是NDK更详细的答案: 查看显示的
\u SC\u PHYS\u页面
和\u SC\u AVPHYS\u页面
是通过读取由Linux内核维护的/proc/meminfo
来实现的。在我使用的配有4GB RAM的联想安卓7.0.1设备上,该文件的前几行如下所示:
以页面大小为单位提供sysconf(\u SC\u PHYS\u PAGES)
值。这似乎是Android可用于代码、数据等的总内存。它比我正在使用的设备上声称的物理RAM少了大约300MB,这可能是由于屏幕缓冲区等原因造成的李>MemTotal
以相同的单位提供sysconf(\u SC\u AVPHYS\u PAGES)
值。这似乎是一个根本没有被使用的内存。在我的4GB设备上,只有大约200MB李>MemFree
MemAvailable
值,没有sysconf参数,该值是可以在需要时提供的RAM。显然这是因为MemAvailable
在2014年初才添加到Linux内核中,而sysconf()支持似乎比这更古老MemAvailable
不是三星安卓5.0,而是亚马逊FireOS 5.6(基于安卓5.1)和摩托罗拉安卓7.1;我不知道6.x
我计划为NDK测试线束(不是将要分发的应用程序)做的是,在了解了这一点之后,使用
MemAvailable
(如果有),否则使用物理RAM大小的一半。由于我必须阅读/proc/meminfo
以确定是否存在MemAvailable
,因此,如果调用sysconf(),让仿生LibC再次读取它是没有意义的 捕获OutOfMemoryException
是否算数?使用的memClass
可以(静态)缩放您的模型。我认为当OutOfMemoryErrors开始抛出时,您基本上已经被套住了。但是谢谢你的文章链接。
#include <unistd.h>
size_t getTotalSystemMemory()
{
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
}
size_t getFreeSystemMemory()
{
long pages = sysconf(_SC_AVPHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
}
MemTotal: 3721064 kB
MemFree: 208108 kB
MemAvailable: 2543032 kB