ขนาดวิดีโอ: 1280 X 720853 X 480640 X 360
แสดงแผงควบคุมโปรแกรมเล่น
เล่นอัตโนมัติ
เล่นใหม่
本当に便利で必須の情報でした。 Unity Japanは最高のチュートリアルを提供しています。
あんまり興味ない話題だったけど解説が上手くて最後まで見てしまった…コードを暗くしたりアニメーションさせて1個ずつ説明するのすごくわかりやすい…
I wish all of my unity content was done by you. This was a very enjoyable video. Your explanation, the background music, the pacing. It was all wonderful.
これまで何回も修正が検討されたうえで、修正が叶わないというのが悲しい
Unityのガベージコレクシ下でリークが起きうるメカニズムが分かりやすい解説で理解できました
Wow I didn't know you could search for "leaked" in the Memory Profiler to find leaked managed shells. Thank you for this video, very insightful!
Thank you for this and eng subtitles.
とても参考になりました!ありがとうございます!
Unity環境でもメモリリークが起きうることを知らなかったので勉強になりました
本当は怖いUnityみたいな感じで面白かったです🥶👻
ACTUALLY the better unity channel, this is crazy good
こんなに重要な情報はスクリプトリファレンスのDestroyの項目に書いてくれ
めちゃくちゃ大事で勉強になる動画でした。頭が痛くなる問題ですが、メモリ・プロファイラーが正式版になったのが救いですかね。ありがとうございます!
とても勉強になります♩メモリリークの解消も軽量化に入るのかな?個人的には軽量化関連もっと見たいです♩
動画内で「MyComponentのOnDestroyでTexture2Dを明示的にDestoryしたほうがよいでしょう」とあるんですが、MyComponentそのものがDestroyされたら参照がなくなるので、MyComponentが管理していたすべてのManaged shellもnative objectも消えると思ったんですが、残ってしまうんでしょうか?(動画内で実際にLeaked Managed Shellを確認して消えていた理由はListをClearしたからと思っています)
Thank you very much, awesome video!
参考にします
Thank you! I love your sharing!!
エンジニアではない私には難しい話だったけど、何とかついていけたと思う(思いたい)^^;いつもありがとうございます。
Thanks! Unity Japan is so good!
解説動画に見せかけて、Unityのヤバいところに付き合ってください動画...
とても参考になる動画です、助かるます、ありがとうございます。ちなみに、Unityの中で leak しません、でも iOS (IL2CPP) にビルドのは leak が発生する、この現象はどんな原因でしょうか?
まじでえええ!!?nullの明示的に代入が必要だなんて、はるか昔あったようななかったような・・・。箱庭系RPG、Valheimとかで追従するペット(長時間破棄されない)を増やしたりすると、ゲームが激重になって、インスタンスも増えてるしメモリがゆるやかに漏れてるなぁーって思ってた。数時間のプレイなら気にならないけどオブジェクト数を増やすと破綻するパターン。nav meshみたいな経路探索AIが複数走ってAgentがぶつかりあって掴んでるんだろうとおもってたけど、単にオブジェクトのDestroyだけでは駄目でnullをぶっこむ必要があるとか、罠すぎない?同じような挙動をするゲーム多いから多分気がついてない開発者山程いそう。Destroy()、Clear()のスクリプトリファレンスに書いておいておくれよ・・・。もしかして音バグと呼ばれるところにも同じ原因か。破棄すると挙動がおかしいから再利用に回してたが・・・
Thank you!!!
C#からC++を参照しているのはm_CachedPtrDestroy()を呼ぶと即時にC++データを破棄する
初学者の身ではサンプルを読み解くだけで難しい……コンポーネントのInstantiateって何が起こるのとか、Destroy(o.gameObject)した時今回の話抜きにそもそもoはどうなるんだろうとかChatGPTに教えてもらってなんとか理解しました
んー?MyComponentクラスで配列やテクスチャが放置されるくだりがよくわかりませんでしたわざわざOnDestroyでnullを突っ込まなくてもMyComponentクラスがDestoryされた際にどこからも参照されてなければMyComponentクラスそのものがGCで回収されるのでフィールドにnullを突っ込まなくも自動的にGCによって回収されるのではないですか?
これには若干の前提知識が要求される話でUnityC#はフロントエンド実装でしかなくコア実装がC++側にある(ここは解説に含まれています。)点です一瞬動画中に登場したのですがUnityのフロントC#実装にあるUnityEngineObject.bindingsクラス にあるCompareBaseObjects(UnityEngine.Object lhs, UnityEngine.Object rhs)で”NULLの定義自体”をオーバーロードしています。(この点も一応動画で一瞬サラッと説明されています)(さらにどうでもいい説明をするとCompareBaseObjectsは同値確認,C#でいうところのequals()的な奴も兼ねてます)(Unityのフロント実装はGithubで読めるので興味あればクラス名でググると読めます)じゃあCompareBaseObjectsは更に何をやってんだって話ですが,内部でGetCachedPtr() というメソッドを叩いてIntePtr.Zeroかどうかを確認しているだけです。IntPtrはネイティブコード側のポインタを格納する型で,UnityObjectの実態とも言えます。つまりC++側との参照が切れてるかどうかでNULLを返しているだけなので実態としてはNULLではなく参照が切れていることを表現している実態が残ります。なので実際のNULLではないという理屈です。そしてNULLが代入されてない以上元々参照を持っているクラスとの参照がやはり残ってしまうのでgcも走りません。Unityの型の多くの実態はC++実装のポインタを持ってるだけです。VS2019とかのデバッガーでも基底クラスを追っかけてm_CachedPtrとか見ると実際の値を確認できます。やはりあくまでもC#の皮を被ったC++プロダクトなんだなと実感できます。 じゃあintPtr.Zeroになったら自動でgcが適用されるべきだろ?とは私も思うんですがどうもそこが上手くいかない理由があるようです、パフォーマンスなのかメモリ安全の保証が困難なのかはわかりませんが・・・NULLの実態を隠蔽するするのはいいとして、Playerloopを一周回して破棄したら自動でC#側のマネージドコードもnullを突っ込んでgc送りにする専用メソッドぐらいは整備してもいいのにとは思います。まあもうUnity自身が20年モノの巨大プロダクトと化しておりIL2CPPとかとのも絡みもあって膨大な依存関係を修正することはもうどうしようもなく不可能な状態なのでしょう・・・
@@ムスカ大佐-t8m 長文で解説して頂いて恐縮ですが、論点がズレてます私はUnityのnull偽装については一切言及してません。MyComponentのOnDestroyの必要性について伺っています
Unity公式の見解も知りたいところですが、サードパーティのライブラリなどの実装がしょぼくてDestroyを呼ぶだけで参照を解放してなかった場合の対策と読みました..
@@ruinzu403 ああ理解しました、深夜テンションで先走ってしまい失礼しました。ああ恥ずかしいので後で消しますねwUniRXのAddto()みたいにアンマネージドメモリは全部デストラクタやOnDestroy()で破棄する習慣をつけましょうね程度のものだと思うのであんまし深い意味はないように思えます。ただ例としては混乱を招く気はするので普通にButtonEventとかで破棄とNULL代入をしたほうがデモンストレーションとしては適切だと思いますね。動画の締めでも長時間残ってるオブジェクトで顕在化する問題だと明言しているのでご指摘はたぶん妥当なものだと思いますが一方で明示的な破棄をするにはNULLを代入するしかやりようがないという最大の論点には特に関係ないので割と不毛な論点かなと?とも思います極端な話PCをシャットダウンすればメモリ開放されるから気にしなくていいよねと話に近いです。
nullを代入しろというのはネガティブなインパクトがありますが、落ち着いて考えると理解はできなくはないと思ってきました。1. まずDestroyが呼ばれたら、見かけ上 nullと表示されてしまうのはUnity側の修正を望みます。2. ここでメモリリークと言われるのは、(主にフィールドで)保持しているオブジェクトをDestroyしてもC#的にそのまま保持されてしまう問題だと思いますので、 プログラマの方はDestroy呼んだとしてもそれだけで安心せずに変数の参照を消しましょう。例えばローカル変数の場合は自動的に消えるはずなので null を代入しなくて良いというものだと思います。(リストに参照がある場合などはもちろんクリアする)逆にいうと、経験が長いプログラマは、参照をわかっているはずなのでこの動画をもって何かを気をつけるというのはないかもしれません。(1. の挙動だけ気をつければ←これが厄介ですが)
Unity エンジンでメモリリークが発生しやすい状況を放置しておいて、その言い方はどうなのか。Destroy 関数で破棄したと思わせておいて実はあるんだよねってインテリぶって語られてもちゃんと直してほしいとしか思わない。
初心者殺し過ぎるww
Unity はこういう落とし穴多すぎて大嫌い 公式のトップに書いておけよ
本当に便利で必須の情報でした。 Unity Japanは最高のチュートリアルを提供しています。
あんまり興味ない話題だったけど解説が上手くて最後まで見てしまった…
コードを暗くしたりアニメーションさせて1個ずつ説明するのすごくわかりやすい…
I wish all of my unity content was done by you.
This was a very enjoyable video. Your explanation, the background music, the pacing. It was all wonderful.
これまで何回も修正が検討されたうえで、修正が叶わないというのが悲しい
Unityのガベージコレクシ下でリークが起きうるメカニズムが分かりやすい解説で理解できました
Wow I didn't know you could search for "leaked" in the Memory Profiler to find leaked managed shells. Thank you for this video, very insightful!
Thank you for this and eng subtitles.
とても参考になりました!
ありがとうございます!
Unity環境でもメモリリークが起きうることを知らなかったので勉強になりました
本当は怖いUnityみたいな感じで面白かったです🥶👻
ACTUALLY the better unity channel, this is crazy good
こんなに重要な情報はスクリプトリファレンスのDestroyの項目に書いてくれ
めちゃくちゃ大事で勉強になる動画でした。
頭が痛くなる問題ですが、メモリ・プロファイラーが正式版になったのが救いですかね。
ありがとうございます!
とても勉強になります♩
メモリリークの解消も軽量化に入るのかな?個人的には軽量化関連もっと見たいです♩
動画内で「MyComponentのOnDestroyでTexture2Dを明示的にDestoryしたほうがよいでしょう」とあるんですが、
MyComponentそのものがDestroyされたら参照がなくなるので、
MyComponentが管理していたすべてのManaged shellもnative objectも消えると思ったんですが、残ってしまうんでしょうか?
(動画内で実際にLeaked Managed Shellを確認して消えていた理由はListをClearしたからと思っています)
Thank you very much, awesome video!
参考にします
Thank you! I love your sharing!!
エンジニアではない私には難しい話だったけど、何とかついていけたと思う(思いたい)^^;
いつもありがとうございます。
Thanks! Unity Japan is so good!
解説動画に見せかけて、Unityのヤバいところに付き合ってください動画...
とても参考になる動画です、助かるます、ありがとうございます。
ちなみに、Unityの中で leak しません、
でも iOS (IL2CPP) にビルドのは leak が発生する、
この現象はどんな原因でしょうか?
まじでえええ!!?
nullの明示的に代入が必要だなんて、はるか昔あったようななかったような・・・。
箱庭系RPG、Valheimとかで追従するペット(長時間破棄されない)を増やしたりすると、ゲームが激重になって、インスタンスも増えてるしメモリがゆるやかに漏れてるなぁーって思ってた。数時間のプレイなら気にならないけどオブジェクト数を増やすと破綻するパターン。nav meshみたいな経路探索AIが複数走ってAgentがぶつかりあって掴んでるんだろうとおもってたけど、単にオブジェクトのDestroyだけでは駄目でnullをぶっこむ必要があるとか、罠すぎない?同じような挙動をするゲーム多いから多分気がついてない開発者山程いそう。Destroy()、Clear()のスクリプトリファレンスに書いておいておくれよ・・・。もしかして音バグと呼ばれるところにも同じ原因か。破棄すると挙動がおかしいから再利用に回してたが・・・
Thank you!!!
C#からC++を参照しているのはm_CachedPtr
Destroy()を呼ぶと即時にC++データを破棄する
初学者の身ではサンプルを読み解くだけで難しい……
コンポーネントのInstantiateって何が起こるのとか、Destroy(o.gameObject)した時今回の話抜きにそもそもoはどうなるんだろうとか
ChatGPTに教えてもらってなんとか理解しました
んー?MyComponentクラスで配列やテクスチャが放置されるくだりがよくわかりませんでした
わざわざOnDestroyでnullを突っ込まなくてもMyComponentクラスがDestoryされた際にどこからも参照されてなければMyComponentクラスそのものがGCで回収されるので
フィールドにnullを突っ込まなくも自動的にGCによって回収されるのではないですか?
これには若干の前提知識が要求される話で
UnityC#はフロントエンド実装でしかなくコア実装がC++側にある(ここは解説に含まれています。)点です
一瞬動画中に登場したのですがUnityのフロントC#実装にあるUnityEngineObject.bindingsクラス にあるCompareBaseObjects(UnityEngine.Object lhs, UnityEngine.Object rhs)で”NULLの定義自体”をオーバーロードしています。
(この点も一応動画で一瞬サラッと説明されています)
(さらにどうでもいい説明をするとCompareBaseObjectsは同値確認,C#でいうところのequals()的な奴も兼ねてます)
(Unityのフロント実装はGithubで読めるので興味あればクラス名でググると読めます)
じゃあCompareBaseObjectsは更に何をやってんだって話ですが,内部でGetCachedPtr() というメソッドを叩いてIntePtr.Zeroかどうかを確認しているだけです。
IntPtrはネイティブコード側のポインタを格納する型で,UnityObjectの実態とも言えます。
つまりC++側との参照が切れてるかどうかでNULLを返しているだけなので実態としてはNULLではなく参照が切れていることを表現している実態が残ります。
なので実際のNULLではないという理屈です。
そしてNULLが代入されてない以上元々参照を持っているクラスとの参照がやはり残ってしまうのでgcも走りません。
Unityの型の多くの実態はC++実装のポインタを持ってるだけです。
VS2019とかのデバッガーでも基底クラスを追っかけてm_CachedPtrとか見ると実際の値を確認できます。
やはりあくまでもC#の皮を被ったC++プロダクトなんだなと実感できます。
じゃあintPtr.Zeroになったら自動でgcが適用されるべきだろ?とは私も思うんですがどうもそこが上手くいかない理由があるようです、パフォーマンスなのかメモリ安全の保証が困難なのかはわかりませんが・・・
NULLの実態を隠蔽するするのはいいとして、Playerloopを一周回して破棄したら自動でC#側のマネージドコードもnullを突っ込んでgc送りにする専用メソッドぐらいは整備してもいいのにとは思います。
まあもうUnity自身が20年モノの巨大プロダクトと化しておりIL2CPPとかとのも絡みもあって膨大な依存関係を修正することはもうどうしようもなく不可能な状態なのでしょう・・・
@@ムスカ大佐-t8m 長文で解説して頂いて恐縮ですが、論点がズレてます
私はUnityのnull偽装については一切言及してません。MyComponentのOnDestroyの必要性について伺っています
Unity公式の見解も知りたいところですが、サードパーティのライブラリなどの実装がしょぼくてDestroyを呼ぶだけで参照を解放してなかった場合の対策と読みました..
@@ruinzu403 ああ理解しました、深夜テンションで先走ってしまい失礼しました。
ああ恥ずかしいので後で消しますねw
UniRXのAddto()みたいにアンマネージドメモリは全部デストラクタやOnDestroy()で破棄する習慣をつけましょうね程度のものだと思うので
あんまし深い意味はないように思えます。
ただ例としては混乱を招く気はするので普通にButtonEventとかで破棄とNULL代入をしたほうがデモンストレーションとしては適切だと思いますね。
動画の締めでも長時間残ってるオブジェクトで顕在化する問題だと明言しているのでご指摘はたぶん妥当なものだと思いますが
一方で明示的な破棄をするにはNULLを代入するしかやりようがないという最大の論点には特に関係ないので割と不毛な論点かなと?とも思います
極端な話PCをシャットダウンすればメモリ開放されるから気にしなくていいよねと話に近いです。
nullを代入しろというのはネガティブなインパクトがありますが、落ち着いて考えると理解はできなくはないと思ってきました。
1. まずDestroyが呼ばれたら、見かけ上 nullと表示されてしまうのはUnity側の修正を望みます。
2. ここでメモリリークと言われるのは、(主にフィールドで)保持しているオブジェクトをDestroyしてもC#的にそのまま保持されてしまう問題だと思いますので、 プログラマの方はDestroy呼んだとしてもそれだけで安心せずに変数の参照を消しましょう。
例えばローカル変数の場合は自動的に消えるはずなので null を代入しなくて良いというものだと思います。
(リストに参照がある場合などはもちろんクリアする)
逆にいうと、経験が長いプログラマは、参照をわかっているはずなのでこの動画をもって何かを気をつけるというのはないかもしれません。
(1. の挙動だけ気をつければ←これが厄介ですが)
Unity エンジンでメモリリークが発生しやすい状況を放置しておいて、その言い方はどうなのか。
Destroy 関数で破棄したと思わせておいて実はあるんだよねってインテリぶって語られてもちゃんと直してほしいとしか思わない。
初心者殺し過ぎるww
Unity はこういう落とし穴多すぎて大嫌い 公式のトップに書いておけよ