実機でのメモリ アクセス中にシステムがダウンする原因を教えてください。
以下のようなメモリ アクセスを実機で行った場合、ARM の仕様上エラーが発生し、 ARM 自身の処理が停止します。
uint16 n[2];
uint16* p;
// 奇数番地のアドレス位置に移動し、
// アラインをまたぐデータの転送を行います。
p = (uint16*)((char*)n + 1);
*p = 0;
このコードでは、uint16 型の配列で連続したメモリ空間を確保し、 char 型分だけアドレス位置をずらしています。 そのアドレス位置から uint16 型のデータを転送しようとするとアラインをまたいでしまうため、 ARM の仕様上エラーが発生します。
その他にも、以下のような場合にシステムがダウンします。
- MALLOC 関数で取得したポインタに NULL チェックをせずにアクセスした場合など、 NULL ポインタへアクセスした場合。
- 配列に対して範囲外のインデックスを指定してアクセスした場合など、 無効なアドレスへアクセスした場合。
端末のメモリの全容量と空き容量を知るには?
端末に搭載されているメモリ容量を取得するには、 ISELL_GetDeviceInfo() を使用します。 また、現在使用されているメモリ容量取得するには、 IHEAP_GetMemStas() を使用します。 この 2 つの値を引き算することで、空き容量を知ることができます。
[ BREW API のみを使用したコード ]
// 端末のメモリ搭載量を取得する
AEEDeviceInfo devInfo;
ISHELL_GetDeviceInfo(shell, &devInfo);
uint32 totalSize = devInfo.dwRAM;
// 現在のメモリ使用量を取得する
IHeap* heap;
ISHELL_CreateInstance(AEECLSID_HEAP, &heap);
uint32 usedSize = heap->GetMemStats();
IHEAP_Release(heap);
// 現在のメモリ空き容量を取得する
uint32 freeSize = totalSize - usedSize;
[ SophiaFramework を使用したコード ]
// 端末のメモリ搭載量を取得する
SFXDevice dev;
UInt32 totalSize = dev.GetRAMSize();
// 現在のメモリ使用量を取得する
SFBHeapSmp heap = SFBHeap::GetInstance();
UInt32 usedSize = heap->GetMemStats();
// 現在のメモリ空き容量を取得する
UInt32 freeSize = totalSize - usedSize;
しかし、たとえば 100KB の空き容量があるからといって、 必ずしも 100KB のメモリブロックを割り当てることができるわけではありません。 MALLOC() と FREE() によりメモリの割り当てと解放を繰り返すと、 メモリの断片化が発生するからです。
特定のサイズのメモリブロックを一度に割り当てられるかどうかを調べるには、 IHEAP_CheckAvail() 関数を使用します。
BREW にガベージコレクションを行うAPIはありますか?
BREW にはガベージコレクションを行うAPIはありません
ヒープの空きサイズより小さいサイズで MALLOC() を行った場合でもメモリ確保が失敗するときがありますが、なぜでしょうか?
「ヒープの空きサイズ = MALLOC() で確保できるヒープサイズ」ではありません。ヒープの 確保/解放が繰り返され、空きブロックが飛び飛びになり、ヒープの空きサイズ分連続して確保できない場合があるためです。
大きなヒープを確保する場合は IHEAP_CheckAvail() を使用して、指定したサイズ分ヒープが確保可能かどうかを調べてください。IHEAP_CheckAvail() は、引数で指定されたサイズの連続したヒープが確保できるかどうかを調べる関数です。
構造体をゼロで初期化するには ?
構造体をゼロで初期化するには ZEROAT 関数を使用してもよいですが、C 言語で次のように書く方が簡単です。
AEEDeviceInfo devinfo = {0};
ZEROAT 関数を使用する場合は、以下のように記述します。
AEEDeviceInfo devinfo;
// 構造体をゼロで初期化する。
ZEROAT(&devinfo);