java - Android内存限制测试问题?

标签 java c# android memory xamarin.android

我在某处读到,单个 Android 应用程序的内存限制为 16MB(对于某些设备可能更高)。因此,在从网络加载某些数据(例如图像)时,情况似乎确实如此。

在我的虚拟设备(Android 版 Visual Studio 模拟器)上,内存限制约为 46MB。我猜想是因为在抛出 OutOfMemoryException 之前我可以加载的图像数量是 46 个图像(每个图像的大小约为 1MB)。

起初我认为只有当图像显示在 ImageView 上(包含在 ListView 或 RecyclerView 的项目中)时,内存才可能超出。但是,无论是否显示加载的图像,仍然会引发异常(我可以在输出窗口中看到它)。

所以我想通过加载某种类型的本地列表来重现 OutOfMemoryException,例如 List<int>项目数量约为 13 000 000(应超过 46MB)。但是,不会引发异常。我什至尝试将项目数量增加到 130 000 000,但仍然相同,没有抛出任何异常。这是代码:

//the local list is declared inside my main Activity class
List<int> _ints = new List<int>();
for(var i = 0; i < 130000000; i++) {
    _ints.Add(i);
}

看来我以错误的方式理解了 OutOfMemoryException 的原因。您能否向我解释一下这一点,或者如果可能的话,给我一些示例代码或建议来重现 OutOfMemoryException 但与从网络下载任何内容无关,我的意思是使其尽可能简单。

最佳答案

您收到的 OutOfMemoryException 来自 Java 端。您无法仅使用 C# 对象来重现它。

您需要分配大的 Java 对象。它不适用于大量小对象,因为从 C# 代码中可以引用的 Java 对象数量是有限的。

Android.Graphics.Bitmap 是一个很好的候选者:

List<Bitmap> _ints = new List<Bitmap>();
for (var i = 0; i < 130000000; i++)
{
    _ints.Add(Bitmap.CreateBitmap(1000, 1000, Bitmap.Config.Argb8888));
}

生成的 Java 异常(包含在单声道异常中):

Java.Lang.OutOfMemoryError: Failed to allocate a 4000012 byte allocation with 219956 free bytes and 214KB until OOM
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <368820a9888f43ddb85d18e87189adbf>:0
    at Java.Interop.JniEnvironment+StaticMethods.CallStaticObjectMethod (Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfomethod, Java.Interop.JniArgumentValue* args) [0x00082] in <a043032cf94a485190047a14918b9f60>:0
    at Java.Interop.JniPeerMembers+JniStaticMethods.InvokeObjectMethod (System.String encodedMember, Java.Interop.JniArgumentValue* parameters) [0x00019] in <a043032cf94a485190047a14918b9f60>:0
    at Android.Graphics.Bitmap.CreateBitmap (System.Int32 width, System.Int32 height, Android.Graphics.Bitmap+Config config) [0x0005e] in <3140893b79904cefbb68181cd89998e0>:0
    at SomeActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00024] in <efd0cb86bcd8422d9a46a0a8a1804b4d>:0
    at Android.Support.V4.App.FragmentActivity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x00011] in <71c3e52f1b484794bca1cdfb1b8b1fdb>:0
    at (wrapper dynamic-method) System.Object:46337ec2-c41a-4805-8728-4ab907d01a03 (intptr,intptr,intptr)
    --- End of managed Java.Lang.OutOfMemoryError stack trace ---
  java.lang.OutOfMemoryError: Failed to allocate a 4000012 byte allocation with 219956 free bytes and 214KB until OOM
      at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
      at android.graphics.Bitmap.nativeCreate(Native Method)
      at android.graphics.Bitmap.createBitmap(Bitmap.java:812)
      at android.graphics.Bitmap.createBitmap(Bitmap.java:789)
      at android.graphics.Bitmap.createBitmap(Bitmap.java:756)
      at md53b9888b0c3fe89a24cb980ab2ea2a8a2.SomeActivity.n_onCreate(Native Method)
      at md53b9888b0c3fe89a24cb980ab2ea2a8a2.someActivity.onCreate(SomeActivity.java:32)
      at android.app.Activity.performCreate(Activity.java:5990)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)

编辑:使用 Xamarin 时,内存问题更加复杂,因为有 2 个垃圾收集器,并且两个垃圾收集器中都存在一些对象(例如位图)。

这在 Xamarin documentation 中进行了解释,特别是章节Helping the GC

关于java - Android内存限制测试问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39950377/

相关文章:

android - 完成之前的 Activity ,机器人?

java - 上传文件到 FTP 服务器时出现异常

c# - 包括具有序列化形式的数组 - jquery

c# - 如何使用 C# .net 从命令行调用带有多个参数的 C++ exe

c# - 如何在 C# 中将数据从子窗体发送到父 MDI 窗体或从父 MDI 发送到子窗体?

android - 在 kotlin 中为 ViewModel 编写单元测试用例

java - 将ResultSet放入HashMap?

java - 禁用当前应用程序的推送通知 android java

java - 使用 mysql 运行 JDBC 程序时出现此错误

java - 在绑定(bind) ListView 之前从数据库中分割字符串