質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

678閲覧

クロージャーとガベージコレクションが理解不能

gvaslkjlie

総合スコア4

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2020/07/27 11:14

###用語集
解説サイトA= https://logmi.jp/tech/articles/322067
画像A= https://img.logmi.jp/article_images/CnNjsbCDuXcau2y612zVvW.jpg
画像B= https://img.logmi.jp/article_images/8ueUvyGywcmH2rx8eTssCM.jpg

抱えている問題・実現したいこと

html・css・javascriptでゲームを作っているが、
「このwebページは多くのメモリを使用しています」と警告が出る。
無視していると強制的にブラウザがページを再読み込みさせてしまうらしい。
ゲームプレイ途中にページが再読み込みされて処理がリセットされては困るので
メモリリークについて理解し、対策を取りたい。

前提

いろいろ解説サイトを読んだが、中でもゲームについて言及している
解説サイトAをメインで読んでいます。
解説サイトAによるとクロージャーがメモリに関係ありそうなので、理解をしたいが、難しくて理解できないです。

###ガベージコレクションが発揮される条件が不明
画像Aに対して「ルートオブジェクトからたどれるものは消せないルール。だから、globalObjから辿り、something関数、NOT_USE_CLOSURE関数、localClosure変数は繋がりがあるので逐一消せなくなります」とありますが、globalObjはleakSampleスコープの中にあるのでルートオブジェクトではありませんよね?それともルートオブジェクトである「var test」のイコールの右辺の中にあるものは全てルートオブジェクトから辿れるとみなされるのですか?

###クロージャーを使わないケースを理解できない
解決先としてクロージャーを使わないソース(画像B)が載っていますが、このソースもクロージャーを使っていませんか?解説サイトAには「別のスコープのローカル変数を参照できる仕組み自体がクロージャ」とありました。画像Bにおいては、nonLeakSampleスコープのローカル変数であるglobalObjを、NOT_USE_CLOSURE関数スコープ内で参照しているので、そう思いました。

備考

以前
https://teratail.com/questions/280194
に質問しましたが、1つの実現したいこと・抱えている問題に対して課題が複数あったので、課題ごとに分けて質問する為、その理由を添えて削除依頼しました。削除依頼は運営にも受理され、現在は削除されています。運営に受理されたということで複数に分けて質問させていただきます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/07/27 11:31

他の原因はつぶしたけど残っている問題として、クロージャ内のメモリリークについて考えているのでしょうか?
gvaslkjlie

2020/07/27 11:50

コメントありがとうございます。解説サイトAに記載されている原因・改善策は大きく分けて5個ですが、対応状況は下記の通りです。 1:使っていないはずのリソースがメモリに残っている ↑ChromeのALLOCATION TIMELINEの見方がわからず他サイトも見て勉強するが行き詰まる。teratailで質問中。 2:グローバル変数はずっと生き続けてしまう ↑ルートに記述しているのはjqueryの「$(function(){ ★ });」であり、処理は全て★に記述しているので、グローバルにはなっていないはず 3:クロージャが成立する起因になったクロージャの変数は、参照されうる可能性があるとメモリに残し続ける。 ↑クロージャーが理解できず他サイトも見て勉強するが行き詰まる。teratailで質問中。 4:GPUを改善する方法で、小手先で唯一できることは、Texture Bufferを作って無駄な描画を減らすことぐらい。 ↑不明点が多数ある中で読み進められないと考え、他が理解できるまで読解は後回しに。 5:JITコンパイラにやさしいコードを書く ↑不明点が多数ある中で読み進められないと考え、他が理解できるまで読解は後回しに。
maisumakun

2020/07/27 11:53 編集

いや、そういう最適化のレベル以前の問題で、「同じエレメントにイベントを何度もセットしている」とか「setTimeoutが増殖している」とか、コードが何かしらのバグを含んでいる、という可能性もあるかと思います。
gvaslkjlie

2020/07/27 12:07

ご回答ありがとうございます。 まさに私の作っているゲームのjsは「同じエレメントにイベントを何度もセットしている」し「setTimeoutが増殖している」状態にあります。 「同じエレメント イベントを何度もセット」と検索しても検索の仕方が悪いのか何がダメなのか情報が出てこなかったので、教えていただければ幸いです。 「setInterval」はclearしないと重くなると何かで読んだのですが、「setTimeout」についてもclearしないと重くなるのか調べてみました。 https://stackoverrun.com/ja/q/999418 によると意見が分かれていたり、node.jsの場合だったり、再起の場合だったりして結局わかりませんでした。
tetosept

2020/07/27 14:01

横から失礼します。 イベントはaddEventListenerで登録する様に必要がなくなればremoveEventListenrする必要があります。 removeしない場合重ね付けされていってしまうので例えばclickイベントを二回addした場合は一回のクリックで登録されたイベントが二回実行されます。 こちらご存知でしたら大変恐縮なのですが、上記コメントで気になったので確認していただければと思います。
gvaslkjlie

2020/07/28 09:27

tetosept様、コメントありがとうございます。「同じエレメントにイベントを何度もセットしている」と記載しましたが誤りでした。正しくは「同じエレメントに対して何度もjqueryのaddClassとremoveClassを繰り返している」でした。紛らわしくてすみませんでした。addEventListenerをソース中で検索しましたが、唯一ヒットしたのが常時必要な関数でしたのでremoveはやめときます。
guest

回答2

0

ベストアンサー

ガベージコレクションが発揮される条件が不明

この記述内容を議論する以前の問題として、ブラウザによっては最適化が行われますので、「スコープから見えているけどまったく参照もされない変数」は消えていることがあります。クロージャから読み書きが行われる変数は、もちろん必要なものなので最適化しても消せません。

(正直言って、実際にそこで行き詰まっているとはっきりしているのでなければ、こんな細かい挙動を追いかけても仕方ありません。)

投稿2020/07/27 11:23

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gvaslkjlie

2020/08/02 03:50

何のタイミングでメモリリークが起きているかがはっきりしていない状況で挙動を追いかけても仕方ないということで、追求するのは一旦終わりにしようと思います。maisumakun様がおっしゃっていた「setTimeoutが増殖している」の部分だけ直すことにします。ご回答ありがとうございました。
gvaslkjlie

2020/08/02 03:51

あとイベントリスナーについても使い終わったら消そうと思います。
guest

0

macOS Catalina上のSafariで「このWebページは多くのメモリを使用しています」の警告が頻繁に出る場合の対処法 | INFORNOGRAPHY

ちなみにこの警告はたとえMacの搭載メモリが32GBや64GBなど潤沢にあってメモリが有り余ってる場合でも表示される。

Safari は表示中のページだけでなくプラグインなども同じメモリを奪い合い、結果この警告が出るようです。
ブラウザを変えてみましょう。

投稿2020/08/02 03:59

編集2020/08/02 04:03
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gvaslkjlie

2020/08/02 10:48 編集

ご回答ありがとうございます。「メモリが有り余ってる場合でも表示される」ということに驚いております。リンク先拝見しましたがユーザーに設定して貰う方法のようですね。ユーザーに設定の手間をかけさせるぐらいなら、Zuishin様の言う通りブラウザを変えてもらうよう、推奨ブラウザ環境を制限しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問