トピック
スー thanks_0u0

メモリについての質問です

GRPエディタのアップデート中なのですが、頻繁にout of memoryエラーに遭遇するようになってしまいました(´=ω= ` ) ですがCLEARの直後は起動出来るのです。何とかエラーを回避したいのですが、メモリの動きがよくわかっていません。 メモリはいつどのように解放されているのでしょうか?また、プログラム終了時にも専有される条件などがあるのでしょうか? どなたかご存知の方がいらっしゃいましたら教えてくださると嬉しいです( ´・ω・` )
7そうだね
プレイ済み
返信[1]
親投稿
Hanzo rzsense
GRPエディターというアプリケーションの必要上、多くの多次元配列変数を定義しているものと拝察致しますが、一旦定義した配列変数を解放する方法は、原則ありません。POPを使って配列変数を削って縮小する方法もあると思いますが、私個人は、どうもPUSH/POP系に苦手意識があって、実施したことはありません。 じゃあ配列変数を解放する簡単な方法がないかと言うと、そうでもありません。DEFによるユーザー定義関数/命令の中で定義した配列変数は、その関数/命令の実行が終われば解放されます。 プログラムの実行中、通しで状態を保存する必要がある場合以外は、この方法を使ってみてはいかがでしょうか。
2そうだね
プレイ済み
返信[2]
親投稿
間違っていたらすみません。 1.CLEAR:SLOT0~SLOT4のグローバル変数使用メモリ解放 2.NEW:指定SLOTのプログラムが使っているメモリ解放  (SLOT省略時はSLOT0~SLOT4)  ・DATA命令のデータ  ・ラベル文字列  ・ローカル変数使用メモリ(エラーなどで中断したとき)  ・その他(名前管理表?) 3.RUN:SLOT0~SLOT3のグローバル変数使用メモリ解放+指定SLOTのプログラムが使っているメモリ解放 4.スマイルボタン:SLOT4のグローバル変数使用メモリ解放+SLOT4のプログラムが使っているメモリ解放+COMMON DEF登録解除 5.ユーザ定義命令(DEF-END)実行終了:ローカル変数使用メモリ解放 6.参照先を指している参照が無くなったとき:参照先使用メモリ解放
2そうだね
プレイ済み
返信[3]
親投稿
スー thanks_0u0
コメントありがとうございます!( ´ u ` ) GRPエディタで使用している配列の殆どがアンドゥ用の配列で240*240や512*512になっていて、また途中でメモリ不足になるのはちょっと嫌なので、サイズが動的に変化しない配列は全てプログラム冒頭で確保しています。 スロット0で起動→終了→スロット4で起動、またはその逆でメモリ不足になるみたいで、コータさんの3.のケースで引っかかってるっぽい感じでしょうか。 最低でもスロット0〜3で起動しているプログラムとスロット4で起動するプログラムの分のメモリか必要なんですね。 CLEARがエディットモードで使えない以上、確実に対処できる方法は無さそうに思えるので、やっぱり地道にメモリを節約していくしか無さそうですね。。。(´・_・`) ともあれ解答ありがとうございます!参考になります!( ´ ▽ ` )ノ
2そうだね
プレイ済み
返信[4]
親投稿
以下のようにすれば、グローバル配列変数の要素数を変えることも出来ます。配列変数の次元や型が違う時には別に定義する必要があります。 DEF NEW_ARY%(N,D) DIM A%[N] FILL A%,D RETURN A% END DIM X%[0] X%=NEW_ARY%(100,0)
2そうだね
プレイ済み
返信[5]
親投稿
残りメモリで最大UNDO回数を変えるとか・・・ちょっとメンドくさいかも
2そうだね
プレイ済み
返信[6]
親投稿
おちゃめ ochame_nako
(起動スロット以外の)指定スロットで使用されているメモリの全開放はUSEを使えばできると思いますが、それでも問題は出ています?
2そうだね
プレイ済み
返信[7]
親投稿
スー thanks_0u0
なるほどー、FREEMEMを見て挙動を変えるのも良さそうですね!( ´ ω ` ) なぬー、USEってそんな使い道があったんですね!Σ(・□・;) そういえばEXECと違って実メモリの確保はされないとか何とかって見たような。。。 という事は、起動スロットを飛ばしてUSE0〜4をしておけば解決なのでしょうか!?それはすごいー、ありがとうございます!プチコン出来るときに試してみますね!( ´ ▽ ` )ノ
0そうだね
プレイ済み
返信[8]
親投稿
USEを使うには、「他SLOTにエラー停止するプログラムがないか、消しても良い」という前提条件が必要だと思われます。 利用者が理解して使う分には問題ないと思います。
2そうだね
プレイ済み
返信[9]
親投稿
Godot orz_127
既にコメントされているかもしれませんが…。 自分の認識では以下の通り。 まず、配列は領域の場所への参照値(ポインタ?)である。 その領域が何処からも参照されなくなったら自動的に消える。 なので別の変数に代入したりで領域の参照元の変数を増やしていなければ新たにサイズ0で確保した領域をその変数に代入すれば、前に参照していた領域は解放される。 また、関数内で宣言した配列は関数をぬけると領域開放されるので、その配列を確保したしたままにしたい場合は、関数外の変数(グローバル変数、引数で渡された変数)に代入しておけば確保されたままになる。 仕様がちゃんと確認できている訳ではないので間違っていたらすみません。 ダイレクトモードが在るのはクローバル変数の領域が確保されたままになっているから? よくわかりません^^;
1そうだね
プレイ済み
返信[10]
親投稿
グローバル変数の領域が確保されたままになっているのは、ダイレクトモードがデバッグ環境を兼ねているからかもしれません。 初期のBASICは、エディタも兼ねていましたし・・・ (グローバル変数しか無かったので、少し大きなプログラムを作ろうとすると、変数名の管理が大変でした^^;)
1そうだね
プレイ済み
返信[11]
親投稿
スー thanks_0u0
USEを試してみましたけれど、やっぱりGRPエディタを使うときは大体プログラムも作りかけになってたりするので、USEの際にエラーで止まっちゃうのは本末顛倒な感じでした( ´・ω・` ) アンドゥはツールを使っている間ずっと使う機能なので、ローカルには出来ないですし。。。 ひとまず素直にメモリ節約を頑張ってみて、駄目そうならFREEMEMでアンドゥ回数を変えるような方法も検討してみます(・u・) 最悪CLEARすれば動く、っていうかGRPエディタ並みにメモリむしゃむしゃするプログラムとの併用じゃなければ動くと思うので、やるだけやってみる、くらいでも良いかなぁ、なんて。。
1そうだね
プレイ済み
返信[12]
親投稿
Godot orz_127
以前は、問題なくて改造中になら付け加えた部分に問題があるような。 そこで動的にメモリを確保する処理とか、新たに大きな領域を確保する処理があるのでは?という感じも。 スーさんの事なのでそんなことは確認済みかと思いますが… 。 この際動的確保は止めて、全て想定の最大値で先に静的に確保する様に変えて見るのはどうでしょう? 適当なことしか言っていませんが何かの参考になれば。
2そうだね
プレイ済み
返信[13]
親投稿
スー thanks_0u0
コメントありがとうございます! 使用途中で落ちちゃうとストレスなので、現状動的確保は極力行わず、静的に確保するようにしていますー(・u・) そして原因もハッキリしていて、今までは最大編集サイズが112x112だったのでアンドゥ配列もそのサイズだったのですけれど、今回のバージョンアップで編集サイズ240x240に対応するために、アンドゥ配列もそのサイズ分必要になってしまった、ということです。 単純にアンドゥ用のメモリが4倍程度に増えたのでメモリが足りなくなってしまったのです。。でも編集サイズを下げてしまうと当初の目的が果たせないので、何か別の対策をしなければならない、っていう状況でございますー(´・_・`)
0そうだね
プレイ済み
返信[14]
親投稿
Godot orz_127
内部構造がよくわからないので適当ですが 座標が0~239でX,Yを別にいれているとして「DIM X%[100],Y%[100]」としていたなら、 1byteは0~255だし、変数%は4byteだし、で。 DIM XY%[50] XY%[0]=&HAABBCCDD AA : X%[0] BB : Y%[0] CC : X%[1] DD : Y%[1] と詰め込めそうですが、そんなことは既に対応済ですね、きっと^^;
1そうだね
プレイ済み
返信[15]
親投稿
スー thanks_0u0
アンドゥは色々な描画形式に対応しないといけないので、座標を保存しているのではなく編集前の画像をそのまま保存しています。GSAVEとGLOADの配列です(・ω・) 実はGSAVEの16bit色モードだと配列の半分はただの無駄なので、そこをキュッとすればメモリも半分で済むかなー、なんて思ったりはしているのですが、速度の面で実用的な範囲に収まるかどうかがわからないので今までやっていなかったのです( ´・ω・` ) 後でそれはやってみようと思っていましたー。
0そうだね
プレイ済み
返信[16]
親投稿
Godot orz_127
プチコン3号の場合、色の物理コードは16bitなので、いくら32bitで頑張っても結局内部的には16bitに丸められ発色は16bitにしかならないので細かい表現はできない仕様だったと。 なので、割りきって色は16bitとしてしまうのは? そうすれば、16bit用の配列ですむのでかなり節約になるのでは? ここら辺もスーさんの方が詳しいと思うので素人考えかも知れませんが^^;
1そうだね
プレイ済み
返信[17]
親投稿
スー thanks_0u0
ありがとうございます。私の1つ前のコメントはGodotさんと全く同じことを言っていたつもりでしたー( ´ u ` )ノ
1そうだね
プレイ済み
返信[18]
親投稿
スー thanks_0u0
やってみたらダメでした(´=ω= ` ) アンドゥ領域は描画直前に保存するので、16bit2つをFORでまとめてる時間は無かったです。省スペースな保存目的とかなら実用的なのですけれど。。。 以前要望トピでもどなたかが要望していましたが、16bit色で配列の1要素に2dot入れるGSAVEはぜひ公式で対応して欲しいところです。。。( ´・ω・` )
0そうだね
プレイ済み
返信[19]
親投稿
スー thanks_0u0
うにににに、、、メモリ節約が難しそうなことが判明したので残りメモリを見てアンドゥ回数を変えようと思ったのですけれど、何故かメモリはあるはずなのにエラーが。。。 DIM時は配列のサイズ以上にメモリが必要だったりするのでしょうか??(´・_・`)
0そうだね
プレイ済み
返信[20]
親投稿
Godot orz_127
さっき、送信に時間がかかっている途中でプチコン配信停止の速報が入ったので、中断したのでコメントがついていなかったようなので、改めて。 2ドットをまとめて、を試して見ましたが、やはり時間が掛かりすぎていまいち。 最初や最後ならまだ耐えられるかも、だけど、途中で時間が掛かるのは耐えられそうにないですorz
1そうだね
プレイ済み
返信[21]
親投稿
Godot orz_127
よくはわかりませんが1バイト単位出はなく、ある程度の最低単位としての大きさがあったような。 1KB とか2KBとか、4KBとか…。 うろ覚えの情報です。 間違っていたらすみません。
1そうだね
プレイ済み
返信[22]
親投稿
スー thanks_0u0
DIRECTモードで試してみました。 ?FREEMEMが8,159,228のとき、定義出来る最大のDIMがA%[500727]でした。 定義後の?FREEMEMは6,156,284なので、全然余裕があるはずなのですけれど。。。(´=ω= ` ) ていうかプチコン配信停止になっちゃうんですか!!残念。。。
0そうだね
プレイ済み
返信[23]
親投稿
私の3DSでは、起動直後のダイレクトモード限定ですが、 DIM A%[(1024+512+256+128+64+32+8+4+2)*1024] が出来ました。 メモリの使われ具合によって、取れる最大数が変わってきます。 そのとき連続して取れるメモリのサイズに依存すると推測しています。 3DS本体の対処も必要な気がします。(気のせいかもしれませんが・・・) プチコンだけの対処で済むならすぐに配信するようになると思います。
1そうだね
プレイ済み
返信[24]
親投稿
スー thanks_0u0
なるほどー、配列だと連続した領域がないとダメなんですね( ´・ω・` ) 確かに起動直後はDIM A%[2079231]まで大丈夫でした。最初のFREEMEMが8,323,068で、DIM後は2,012。2079231*4が8,316,924なのでほぼキッチリ使えてる計算ですよね。 でも連続領域があるかどうかまではわかりませんし、一先ず余りサイズだけを見て、ダメならCLEARしてね、っていうダイアログを出すくらいが精一杯かもですね。ありがとうございます!( ´ ▽ ` )ノ
1そうだね
プレイ済み
返信[25]
親投稿
スー thanks_0u0
HBL?はよくわからないのですが、ソフトのバグが無ければ出来ないんですよね、多分。 本体のファームウェアで対応できるなら既にやっているような気がしますし、地道な修正しかないような雰囲気は感じます(´=ω= ` )
0そうだね
プレイ済み
返信[26]
親投稿
myu314 myu314
一応高度サウンドユニットのARYOPを使えば、240x240の画像ならNew3DSで6msくらい…旧3DSが3倍かかるとして1〜2Fくらいで合成できるようです…といっても、追加コンテンツは躊躇しますよね。 まともに対処するなら、240x240まるごと保存を止めて編集した範囲だけリングバッファに貯めていく(Undo数は可変)だと思うんですが、相当影響範囲大きくなるので対費用効果考えるとUndo数減らすのがよさそうです。 16bit整数型さえあれば! もしくは文字列型・整数型間でCOPYが使えたらなぁ…。
1そうだね
プレイ済み
返信[27]
親投稿
スー thanks_0u0
高度サウンドユニットは持っているけど使い方がわからないので腐っています(ノ´∀`*) そして一応このエディタを使って下さっている方がいらっしゃるのもあって、高度サウンドユニット限定には出来ないかな、って思っています。 編集範囲のみの保存は、うーん、どうすれば。。。巨大なアンドゥ用配列を1つ用意して、1要素目にサイズを格納してそのサイズ分画像を格納、次の要素にまたサイズ、みたいな感じかなぁ。。あ、サイズは別配列に入ってるか。 新しくアンドゥ情報を保存するときにはサイズを先に出して、そのサイズが確保出来るまでアンドゥ情報を追い出す?なんか難しそう。。。 やっぱり16bit整数型があると良いですよね。つけてくれるかなぁ( ´ u ` )
0そうだね
プレイ済み
返信[28]
親投稿
スー thanks_0u0
ひとまず、メモリサイズを見てアンドゥ回数を変えるようにして、ちゃんとメニューから終了した場合は大きい配列を要素0にしてから終わるようにしました(・u・) やるだけはやったかな、って気はしています!皆様のご助言が無ければ出来なかったことだと思いますー、ありがとうございます!( ´ ▽ ` )ノ
0そうだね
プレイ済み
返信[29]
親投稿
スー thanks_0u0
無事(?)v1.80aをリリース出来ましたので、このトピックは円満解決で閉めさせていただきます! 答えてくださった皆様、本当にありがとうございました!( ´ ▽ ` )ノ
0そうだね
プレイ済み