小编Mik*_*ike的帖子

MonoTouch不稳定性仍在继续:托管内存分配器崩溃

简而言之:我可以分配大量非托管内存,但尝试在托管内存中分配相同数量(或更少)会导致GC_remap中的MonoTouch崩溃(下面的callstack).

细节:

我将谈谈上面描述的行为的一个例子.我的应用程序偶尔会分配一个2.5MB大小的托管内存(使用新的byte []),并且它经常在我的iPhone4上死掉,下面粘贴了callstack(即分配期间的mprotect错误).我没有比单个函数调用更长时间地引用这些2.5MB块.

MonoTouch的人说'mprotect errno 12'意味着你已经耗尽了设备上的内存,但问题是,我的应用程序可以使用大量内存.我可以在我的应用启动时分配0MB,10MB200MB非托管内存(使用Marshal.AllocHGlobal),每帧都触摸它,它对我的​​应用程序的行为或此mprotect错误的频率没有区别.

一些笔记

  • GC.TotalMemory告诉我,我的应用程序一直处于3MB5MB的托管内存使用量之间.
  • 我在我的应用程序中有其他地方,我正在分配更大的非托管内存块,它永远不会在那里崩溃.我创建了压力测试,加载4MB(非托管)纹理数据,将其交给GL,并在每一帧绘制它,应用程序坚如磐石,直到我开始要求大块的托管内存.
  • 除非我自己调用GC.Collect,否则GC.CollectionCount几乎没有变化.
  • MonoTouch 3.2.3以及MonoTouch 4.0也会出现同样的情况.
  • 所有测试设备(iPhone 3G,3GS,4,iPad,iPad2)都会出现同样的情况.
  • 在发布版本和调试版本中也会发生相同的行为,尽管调试版本会更频繁地发生.

引发崩溃的方法

  • 如果我创建一个循环调用GC.Collect,然后休眠1ms,这会使崩溃更快发生(即,如果我在调试版本中,几乎立即).
  • 使用某些.NET功能(如WebRequest)也会导致此崩溃.我只能假设它在那里的某个地方分配大块的托管内存.

崩溃的方式

有两种方法可以减少崩溃的频率或完全修复它:

  1. 如果我预先分配2.5MB大小的托管内存,然后在应用程序的生命周期中保留它,那么就不会崩溃.
  2. 如果我在做任何事情之前将2.5MB的内存固定,那么这似乎有所帮助.

结论/问题

由于这个问题,我们尚未在我们的应用程序中实现完全稳定性.这个崩溃(总是在GC_remap中)发生在我们整个应用程序的随机分配中(我在这里的2.5MB示例就是我选择隔离和重新编写的那个).

问题:

  1. 我根本不信任托管分配器吗?
  2. 为什么我可以分配200MB的非托管内存,但是当我要求2.5MB时,托管分配器会死掉?(注意:即使我没有分配200MB的非托管内存,当我要求2.5MB时也会死掉).
  3. 为什么如果我在应用程序的生命周期内占用2.5MB这个应用程序是完全正常的,但是如果我把它还给系统(并调用GC.Collect)并要求另外2.5MB以后,那么崩溃就更糟了!如果这确实是一个内存不足的情况,那么给系统回馈2.5MB是不是更好呢?

我们甚至可以使用MonoTouch吗?

我的团队正在认真考虑放弃MonoTouch用于我们的产品,因为我们无法让它稳定可靠.

我们也无法从MonoTouch团队获得堆栈溢出,在Novell网站上提交错误,或直接通过电子邮件发送MonoTouch的支持电子邮件.我们已将(托管和非托管)内存使用量减少到荒谬的低点,但由于此问题,应用程序仍然崩溃.

在短期内,我想到的唯一解决方法是在启动时分配一大块内存(2-5MB),将其设为PIN,以便垃圾收集器永远不会触及它,并编写我自己的分配器来分配部分内存.这个内存块根据需要阻止我的应用程序.但如果这是MonoTouch下可能的最佳解决方案,那么只要我能从MonoTouch获得逃逸速度,我就会想要我的钱.

...

Mprotect failed at 0xaa00000 (length 3801088) with errno 12
Stacktrace:

  at MyApp.GameScreen/VerifyPictureDialog.StoreBasePictureData () [0x00000] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:428
  at MyApp.GameScreen/VerifyPictureDialog.ApplyFilters (bool) [0x0004b] …
Run Code Online (Sandbox Code Playgroud)

iphone-sdk-3.0 xamarin.ios ios4

8
推荐指数
1
解决办法
1023
查看次数

AVAssetWriterInput和readyForMoreMediaData

AVAssetWriterInput的readyForMoreMediaData是否在后台线程中更新?如果readyForMoreMediaData为NO,我可以在主线程中阻塞并等待值变为YES吗?

我通过向其推送数据来使用AVAssetWriterInput(即不使用requestMediaDataWhenReadyOnQueue)并且我设置了expectedMediaDataInRealTime,并且99.9%的时间我可以在其上调用appendSampleBuffer(或appendPixelBuffer),就像我的应用程序可以生成帧一样快.

除非您在AVAssetWriter会话中间将设备(iPhone 3GS)置于睡眠状态15分钟左右,否则此工作正常.唤醒设备后,appendPixelBuffer有时会收到一条错误消息,"当readyForMoreMediaData为NO时,无法追加像素缓冲区".因此我的问题 - 如何最好地响应readyForMoreMediaData = NO,如果我可以在主线程中稍等一下,如下所示:

while ( ![assetWriterInput readyForMoreMediaData] )
{
    Sleep for a few milliseconds
}
Run Code Online (Sandbox Code Playgroud)

iphone avfoundation iphone-sdk-3.0 ios4 avassetwriter

7
推荐指数
1
解决办法
5631
查看次数

MonoTouch - WebRequest内存泄漏和崩溃?

我有一个使用3.5MB文件进行HTTP POST的MonoTouch应用程序,它在我测试的主要平台上非常不稳定(带有OS 3.1.2的iPhone 3G和带有OS 4.2.1的iPhone 4).我会描述我在这里做的事情,也许有人可以告诉我,如果我做错了什么.

为了排除我的应用程序的其余部分,我将其缩小为一个小样本应用程序.该应用程序是一个iPhone OpenGL项目,它只做这个:

  1. 在启动时,以30k块分配6MB内存.这模拟了我的应用程序的内存使用情况.
  2. 将3.5MB文件读入内存.
  3. 创建一个帖子来发布数据.(创建一个WebRequest对象,使用GetRequestStream(),然后写入3.5MB数据).
  4. 当主线程检测到发布线程完成时,转到步骤2并重复.

此外,每个帧,我分配0-100k来模拟应用程序做某事.我没有保留对这些数据的任何引用,所以应该收集垃圾.

iPhone 3G结果:该应用程序上传了6​​到8次,然后操作系统将其杀死.没有崩溃日志,但有一个LowMemory日志显示该应用程序已被丢弃.

iPhone 4结果:第11次上传时出现Mprotect错误.

一些数据点:

  • 随着应用程序继续上传,仪器不显示内存增加.
  • 仪器没有显示任何重大泄漏(总共1千字节).
  • 使用一个Stream.Write()调用是以64k块还是一次性写入后置数据并不重要.
  • 在开始下一次上传之前,我是否等待响应(HttpWebRequest.HaveResponse)并不重要.
  • POST数据是否有效无关紧要.我尝试使用有效的POST数据,我尝试发送3MB的零.
  • 如果应用程序没有为每个帧分配任何数据,那么内存耗尽需要更长的时间(但如前所述,我分配每个帧的内存在分配它的帧之后没有被引用,所以它应该是由GC舀起来).

如果没有人有任何想法,我会向Novell提交一个错误,但我想先看看我是否做错了.

如果有人想要完整的示例应用程序,我可以提供它,但我已经粘贴了下面的EAGLView.cs的内容.

using System;
using System.Net;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using OpenTK.Platform.iPhoneOS;
using MonoTouch.CoreAnimation;
using OpenTK;
using OpenTK.Graphics.ES11;
using MonoTouch.Foundation;
using MonoTouch.ObjCRuntime;
using MonoTouch.OpenGLES;

namespace CrashTest
{
    public partial class EAGLView : iPhoneOSGameView
    {
        [Export("layerClass")]
        static Class LayerClass ()
        {
            return iPhoneOSGameView.GetLayerClass ();
        }

        [Export("initWithCoder:")]
        public EAGLView (NSCoder coder) : base(coder)
        { …
Run Code Online (Sandbox Code Playgroud)

memory-leaks webrequest xamarin.ios

5
推荐指数
1
解决办法
1067
查看次数

需要从RGB帧创建webm视频

我有一个应用程序,生成一堆jpgs,我需要变成一个webm视频.我正在尝试将jggs中的rgb数据转换为vpxenc示例.我可以在输出视频中看到原始jpgs的基本形状,但是所有内容都是浅绿色(即使是应该是黑色的像素大约是绿色的一半),并且每隔一条扫描线都有一些垃圾.

我正在尝试提供VPX_IMG_FMT_YV12数据,我假设其结构如下:

对于每个帧8位Y数据每个2x2 V块的8位平均值每个2x2 U块的8位平均值

这是一个源图像和即将发布的视频的屏幕截图:

图片

我完全有可能错误地进行RGB-> YV12转换,但即使我只编码8位Y数据并将U和V块设置为0,视频看起来也差不多.我基本上通过这个等式运行我的RGB数据:

// (R, G, and B are 0-255)
float y = 0.299f*R + 0.587f*G + 0.114f*B;
float v = (R-y)*0.713f;
float u = (B-v)*0.565f;
Run Code Online (Sandbox Code Playgroud)

..然后,以产生2×2为U和V,我写入vpxenc滤波值,我只是做(A + B + C + d)/ 4,其中a,b,C,d为的U或V值每个2x2像素块.

所以我想知道:

  1. 是否有更简单的方法(在代码中)获取RGB数据并将其提供给vpx_codec_encode以获得一个不错的webm视频?

  2. 我的RGB-> YV12转换错了吗?

任何帮助将不胜感激.

rgb yuv video-encoding webm libvpx

4
推荐指数
1
解决办法
2469
查看次数

帮助理解MonoTouch崩溃日志

我的MonoTouch应用程序(发布版本)随机崩溃,我在崩溃日志中得到了这个.不幸的是,我没有看到任何与我的应用相关的有用信息.看起来它在MonoTouch和iOS的内部深处.

我在带有OS 3.1.2的iPhone 3G上运行它.

任何人都可以帮我理解这个崩溃日志的含义吗?


Incident Identifier: 222781AB-0F7C-4E1D-9E10-6EE946D6C320
CrashReporter Key:   0ee985a48f32f63b7e50536870f06a1ab4122600
Process:         MyApp_iOS [593]
Path:            /var/mobile/Applications/095A615B-2F9B-4A84-B0E3-EF1246915594/MyApp_iOS.app/MyApp_iOS
Identifier:      MyApp_iOS
Version:         ??? (???)
Code Type:       ARM (Native)
Parent Process:  launchd [1]

Date/Time:       2011-03-24 13:04:18.479 -0700
OS Version:      iPhone OS 3.1.2 (7D11)
Report Version:  104

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

Thread 0 Crashed:
0   dyld                              0x2fe125b2 ImageLoaderMachOCompressed::findExportedSymbol(char const*, ImageLoader const**) const + 58
1   dyld                              0x2fe0dcd6 ImageLoaderMachO::findExportedSymbol(char const*, bool, ImageLoader const**) const + 30
2   dyld                              0x2fe0ee6e …
Run Code Online (Sandbox Code Playgroud)

xamarin.ios

1
推荐指数
1
解决办法
1077
查看次数