🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

Q&A

解決済

3回答

2169閲覧

JavaScript appendした要素はinnerHTMLでメモリから消せるのか

arta

総合スコア20

JavaScript

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

0グッド

0クリップ

投稿2021/01/11 04:20

タイトルの通りです
appendで追加した要素はremoveで消せるのはわかります
innerHTML=""とした場合に、メモリから消えてるんでしょうか
下記2つの差異を教えて下さい

div = document.createElement("div"); document.body.append(div); document.body.remove(div);
div = document.createElement("div"); document.body.append(div); document.body.innerHTML="";

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

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

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

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

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

m.ts10806

2021/01/11 04:21

仰っている「メモリ」をどういう想定で用語使われてますか?
hoshi-takanori

2021/01/11 04:51

innerHTML を設定すると、その内容で上書きされますので、過去に追加したものは画面 (の内容を表示するための DOM ツリー) からは消えます。メモリから消えるかどうかは、変数 div をその後どうするかによります。
arta

2021/01/11 04:59 編集

画面から消えるのはわかります 消えただけでメモリを食ってますよね forで1000回appendした場合に innerHTMLでメモリ上から解放されるわけではないんですか? そのあとの処理というのはどういった処理ですか? removeが必要なんでしょうか?
arta

2021/01/11 05:02 編集

本題の通り差異があるか ないのかすらわからずにいます appendでメモリを食うのか?ということすらもわかりませんが、(恐らく関係してそうですが1000回appendしたら重くなる&下手したらフリーズ=これがメモリを食ってるとの結論) 確認する方法等ありましたらお教え願いたいです
hoshi-takanori

2021/01/11 05:03

「変数 div をその後どうするか」というのは、例えば別のところに append すればそっちで使われるし、div がグローバル変数ならずっと参照されたまま残るということです。div がローカル変数なら、関数を抜ければ div を参照するものがなくなりますので、いずれ GC (ガベージコレクション) にひっかかってメモリから消されることになります。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Memory_Management https://ja.javascript.info/garbage-collection https://www.html5rocks.com/ja/tutorials/speed/static-mem-pools/ https://qiita.com/tkdn/items/ea4f034e0d661def244a
think49

2021/01/11 05:16

> removeが必要なんでしょうか? 逆に聞きますが、「remove() したらメモリから開放される」と思った根拠はどこにありますか。 「remove()してもメモリから開放されないコード」は作ろうと思えば作れます。
guest

回答3

0

javascript

1document.body.remove(div);

↑これだとbodyがundefinedになります。正しくは↓

javascript

1document.body.removeChild(div);

メモリの話ですが、「DOMツリーから消えるか」という意味で言うなら、innerHTML = "" でも body.childNodes の中身は0件になりますが、実メモリが開放されるかどうかは、上の方が言われるように参照が切れているかどうか、だと思います。

JavaScriptの場合、変数のライフサイクルは関数スコープによって決まり、定義の仕方によって変数の配置場所は変わるため、一概には言えないところがあります。

javascript

1<script> 2a = 1 3function hoge() { 4 var b = 2 5 var c = 3 6 d = 4 7 8 function fuga() { 9 console.log(c); 10 } 11 12 window.addEventListener('click', fuga); 13} 14 15hoge(); 16</script>

上記のHTMLを表示した場合、

  1. a はグローバル変数。明示的に消さない限り、windowオブジェクトに保持され続ける。
  2. b はhogeのローカル変数。hoge実行終了後、参照するものがいないので削除される。
  3. c はhogeのローカル変数。ただし、fugaが参照しており、fuga はwindowにリスナー登録されて生き続けるため、hoge実行終了時、fugaのクロージャ(レキシカルスコープ)にcがコピーされて生き続ける。
  4. d は var が付いてないので、hogeのローカルに見せかけてグローバル変数。aと同じ扱い。

※"use strict"モードを使うと、dのような宣言の無い暗黙のグローバル変数が許されなくなるので、普通は"use strict";をスクリプトの先頭に記載します。

質問の「div」がremoveやinnerHTML = ""によって消えるかどうかは、どちらでも bodyのchildNodesから消えるのは確かですが、メモリから消えるかどうかは、divをどうやって定義し、どう使ったかによるという事ですね。

投稿2021/01/11 06:55

umau

総合スコア831

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

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

0

ベストアンサー

ガベージコレクション(Garbage Collection)

JavaScriptではGarbage Collection(以降、GCと呼称)によって不要になったメモリが開放されます。

JavaScriptにおける「不要になったメモリ(データ)」とはどこからも参照されなくなったデータのことです。
グローバル変数はグローバルオブジェクトのプロパティとして参照されます。

HTML

1<script> 2'use strict'; 3var globalVar = 1; // グローバル変数の宣言 4delete this.globalVar; // グローバルオブジェクトのプロパティから削除する(参照を切る -> GCがメモリから開放する) 5</script>

クロージャは関数オブジェクトが変数を参照する為、該当関数が他から参照されている限りはメモリから開放されません。

HTML

1<script> 2'use strict'; 3(function () { 4 var localVar = 1; 5 6 function handleClick (event) { // localVarを参照する 7 console.log(localVar); 8 } 9 10 document.addEventListener('click', handleClick, false); // DOMEventsから参照され、handleClickを参照する 11 document.removeEventListener('click', handleClick, false); // DOMEventsからの参照が切れる -> GCがメモリから開放する 12}()); 13</script>

handleClick への参照は生きていますが、大本のDOMEventsからの参照が切れるので、これら全てがメモリから解放されるはずです。


※IE6全盛期には循環参照問題がありましたが、今は気にしなくて良いでしょう。

ただし、クロージャで意図せずメモリから開放されない変数を量産してしまうコードは今でも少なからず確認できます。
無駄にメモリを消費しない為に正しい知識を身につけておく必要はあります(バグでは有りません)。

Element#innerHTML

appendで追加した要素はremoveで消せるのはわかります
innerHTML=""とした場合に、メモリから消えてるんでしょうか

remove(), innerHTML 共に条件は変わりません。
どこからも参照されなくなれば、自動的にメモリから開放されます

Chrome Developper Tools

メモリ開放ロジックは実装依存の為、詳しくは確認対象ブラウザのDevelopperToolsでメモリ使用量を確認して検証してください。

Re: arta さん

投稿2021/01/11 05:13

think49

総合スコア18189

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

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

0

HTMLinnerHTMLを空に上書きするのはメモリから消すとは言わないでしょうね
div自体はdomとしてメモリ上に残っています

投稿2021/01/11 05:18

yambejp

総合スコア116665

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問