1

問題があります: Texture2D.ReadPixelsでスクリーンショットを作成しようとすると、一部のデバイス (特に iPod 4G) でゲームがクラッシュします。おそらく、メモリ不足が原因で発生します。スクリーンショットを作成する前に、必要な量のメモリを安全に割り当てることができるかどうかを検出し、クラッシュすると思われる場合はプレーヤーに警告を表示したいと考えています。

ただし、テクスチャなどのリソースは Mono VM の外部で管理されているようです。System.GC.GetTotalMemory は、16 MB のアトラスがある場合に 9 MB を返します。そのため、そのためのプラグインを作成する必要があるようです。

(メモリ不足の警告を受け取らなかったと説明するセクションがありましたが、それについては間違っていたようで、Objective-C レベルでは、警告は正常に発生しています)。

クラッシュせずに割り当てることができる「空き」メモリの量を取得するにはどうすればよいですか? 私が望む機能を達成するための他の方法があるかもしれませんか?

4

3 に答える 3

6

あなた自身の答えを説明するには: これは客観的な C コードではなく、カーネルから統計を取得するために Mach API を使用する単純な古い C コードです。Mach API は、XNU によってエクスポートされた低レベル API です。XNU は、トップ レイヤー (UN*X でよく知られている通常のシステム コールと同様に、BSD API をエクスポートします) と最下層 (Mach) で構成されるハイブリッド カーネルです。このコードは、(とりわけ) リソースの OS レベルの使用率に関する統計を提供する Mach の「ホスト」抽象化を使用します。

具体的には、完全な注釈を次に示します。

#import <mach/mach.h>       // Required for generic Mach typedefs, like the mach_port_t
#import <mach/mach_host.h>  // Required for the host abstraction APIs.

extern "C" // C, rather than objective-c
{

    const int HWUtils_getFreeMemory()
    {
        mach_port_t host_port;             
        mach_msg_type_number_t host_size;
        vm_size_t pagesize;

        // First, get a reference to the host port. Any task can do that, and this
        // requires no privileges
        host_port = mach_host_self();
        host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);

        // Get host page size - usually 4K
        host_page_size(host_port, &pagesize);

        vm_statistics_data_t vm_stat;

        // Call host_statistics, requesting VM information. 

        if (host_statistics(host_port,  // As obtained from mach_host_self()
             HOST_VM_INFO,              // Flavor - many more in <mach/host_info.h>(host_info_t)&vm_stat,                  // OUT - this will be populated
             &host_size)                // in/out - sizeof(vm_stat). 
              != KERN_SUCCESS)         
            NSLog(@"Failed to fetch vm statistics"); // log error

        /* Stats in bytes */
        // Calculating total and used just to show all available functionality

        // This part is basic math. Counts are all in pages, so multiply by pagesize
        // Memory used is sum of active pages, (resident, used)
        //                       inactive,      (resident, but not recently used)
        //                   and wired (locked in memory, e.g. kernel)

        natural_t mem_used = (vm_stat.active_count +
                              vm_stat.inactive_count +
                              vm_stat.wire_count) * pagesize;
        natural_t mem_free = vm_stat.free_count * pagesize;
        natural_t mem_total = mem_used + mem_free;
        NSLog(@"used: %u free: %u total: %u", mem_used, mem_free, mem_total);


        return (int) mem_free;
    }
于 2013-09-25T11:55:14.267 に答える
1

Unity3D (iOS および Android) でピクセルを読み取るときに、GL_OUT_OF_MEMORY エラーも発生します。多くのテストを行った後、主な問題は、ReadPixels メソッドを使用してスクリーンショットを撮ると、ゲームのドロー コールが高すぎることです (約 > 40 ドロー コール)。たぶん、この要因も調査する必要があります。

于 2013-10-07T01:03:17.520 に答える