LoginSignup
0
0

More than 3 years have passed since last update.

Dalvik Heapメモリは高すぎ

Last updated at Posted at 2020-07-17

今回の主な話題:「Dalvik Heapメモリは高すぎ」、「Unity 5とUnity 2017でのフレームレートが低下」、「Animator.Initialize警告をどのように処理する」。


メモリ

Q1:ゲームに入るばかりの時、Dalvik Heapメモリは異常に高いので、PSSも高く導く。バックグラウンドに一度切り替えて、ゲームに戻すとDalvik Heapメモリはかなり減少した。そして、ネットで調べられたAndroidでGCを呼び出す方法を使ってみた。System.GC、 runFinalizationとの結合、Runtime.getRuntime().gc()を使うなど、全て有効に減少することができない。これを一回有効に呼び出す方法があるかどうか?

原因がわかった。Android層に一つのSplashを書いた。このSplashはpngタイプので、解像度は1920x1080であり。前には
int splash_bg = getResources().getIdentifier(bgName, "drawable", getPackageName());
m_BgView.setBackgroundResource(splash_bg);

この画像はHideSplashで遊離されており、JavaのGCが呼び出された後に回収される。しかし、実際の画像が100MBぐらい増えさせるはずはない。SplashとSplashVideoだけのテストプロジェクトを使った、コードは完全に同じのに、メモリはそんなに多く増えられない。解釈できるのは、JVM後のあるメモリ配分アルゴリズムは原因になるかもしれない。元々低い場合には配分が少なく、一定の数に達し、再び配分すると、さらに大きな1つのメモリが配分される(Android基層には苦手)。

以降では、まずgetResourcesからBITMAPを取得し、ImageViewに伝える。HideSplashの際に、BITMAPを呼び出すような手動解放方法に変更した。


制作

Q2:一つのMeshRendererに二つの材質がある。他のMaterialPropertyBlocksを設定させたいのに、現在にはできる方法はまだありませんとわかった。RendererからMaterialPropertyBlockを手に入れた後に、指定してある材質に応用することはもうできないでしょうか?みなさんには良い解決策があるのか?

そうです。MaterialPropertyBlocksはMaterial単位ではなくMeshRenderer単位である。Meshを分割し、一つのRendererにMaterialが一つしかないを確保すると問題主に提案する 。


パフォーマンス

Q3:最近プロジェクトをUnity4からUnity5やUnity 2017にアップグレードした後、ローエンドモデルでのフレームレートは10以上低下した。Adreno Profilerで調べた結果はGPU Boundである。

社内のゲームはフレームレートへの要求は高いので、ゲームをする時には必ずフルフレームで実行する。だからこの問題は明らかに見られる。努力して、最後に分かったのはUnity5以後、デフォルトでBlitが開いた、解像度が高いほどGPUの圧力が大きくなる。特にローエンドモデルで、私たちはAdreno405でテストした、Unity4ではフルフレームできるが、Unity5やUnity 2017では最高45くらいまで、これはひどい。幸運なのは、Unity2017.2に、公式がBlitの禁止設定を開放したが、Unity5はその運がない。公式からの情報による、当分Unity5.6にこの機能を導入する計画はない。

こちらを参照してください:https://forum.unity.com/threads/big-performance-issue-with-unity5-on-android.338847


メモリ

Q4:この「Triggers RebuildInternalState」は物体を隠す時に必ず引き起こされるか?Profilerの最後列に必ずWarningがあるので、厳重な間違いを感じた。これをどうやって避けるのか?(前にキャッシュしたことがある場合に)Animator.Initializeの時間コストを明らかになさせるか?
1.png

これはAnimationの含むGameObjectがDeactiveされたときのエンジンWarning、多くの状況には確かに高いCPU時間コストを導く。それに対して、問題主にGameObjectが要らない時に直接に画面の外に移して、GameObjectをDeactiveするではなく、掛けたComponentをDisableさせると提案する。これでInternalStateの発生をRebuildできる。


Unreal 4 レンダリング

Q5:こんにちは、UWAのグローバルイルミネーションに関する記事を見て、いくつかの質問がある。
1.UnityのLightmapベイクをする時に、なぜNormal mapからNormal情報を得られないの?UnrealのLightmassも二枚の図をベイクする、一枚は方向に一枚は色。その色はNormalMapの影響を受けるの?
2.Unrealの一つシーンには複数枚のLightmapがある。例えば昼から夜にかけて、グラデーションはどのように融合しているか?

1.LightmapにおけるDirectional情報とは、ベイクライトの方向情報である。Lightmapでは、一枚が光線のIntensity を記録し、もう一枚はDirecitonalを記録することである。このDirecitonalはShadingの方向に関する計算を参加するの為、例えば、ハイライト計算やnormal計算など。ただのDffuseでもNormalmapが要らない、このDirectional情報を削除し、メモリ占有と計算量を減らすことができる。通常、材質に見られるNormalmapとは、メッシュのNormalであり、Lightmapに記録されているDirectionalとは一つではない。
2.UnrealにおけるPrecomputed Lighting Scenariosは複数セットのLightmapやイルミネーション設定を保存している。できるのはイルミネーションと合わせてLightmapを切り替えることだけ、今には融合はまだ不可能だ。

Q6:ベイクする時イルミネーションのIntensityはbeastのようにNormalを考慮する。Lightmassベイクする時にはNormalmapを提供できるの?

Unityはベイクする時、放射度を使っている。すなわちまずモデルをブロックに分けて、そしてブロック間の反射を計算して、Normalmapは使わない。Normalmapが提供するのは詳細的な情報であり、グローバルイルミネーションに間接光の計算結果は低周波ので、,高周波の情報を入れると必ず良い効果が得られるではない。Unreal 4のLightmassには、Staticタイプの光源がベイクする時にnormalmapを使わせる設定オプションがあり、project settings->engine rendering->lightingに含まれている。


UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析最適化ソリューション及びコンサルティングサービスを提供している会社でございます。

UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0