ワクワクV020回目オブジェクトとメモリモデル(2020-11-14)

2
ほえほえ@スプシマン @hoehoe1234

ワクワクV 20回目 20201114 オブジェクトとオブジェクトの解説です。当塾では変数を理解するためにただしメモリモデル、概念の説明からしています。使うだけでなくて作る方になるにはまずは正しい概念が必要ですので。ただ、VBAのようなスクリプト言語では実際にこのような動きになっているか pic.twitter.com/vjh5zARgjn

2020-11-16 01:49:52
拡大
ほえほえ@スプシマン @hoehoe1234

どうかは確認の使用ががありません。ローカル変数、静的変数はほぼそうなっているでしょうがオブジェクトが生成されるヒープ領域はまとめて取得/静的領域を最初から確保しているような可能性があるからです。とはいえ、一般的にこのようになっている。とうのは概念を理解する上で有効でしょう。

2020-11-16 01:52:01
ほえほえ@スプシマン @hoehoe1234

画面右にあるようにメモリは3つの種類に別れます。実行コード部分を含めれば4つとなります。このメモリの基本を抑えることはVBAに限らずプログラムをしていく上で、挙動を理解するためにもっとも基本的な知識となります。このような知識は不要との考えもあり、それも一理あるのですが、

2020-11-16 01:55:21
ほえほえ@スプシマン @hoehoe1234

当塾では「自分でシステムを作れるようになる」という目的がありますのでこのような仕組み・概念についても解説しています。 メモリ領域は4つに分けられます ①スタックと呼ばれる領域 ②データセグメントと呼ばれる領域 ③ヒープと呼ばれる領域 ④テキストセグメントと呼ばれる領域 です。

2020-11-16 01:57:20
ほえほえ@スプシマン @hoehoe1234

スタック上に確保された変数はローカル変数と呼ばれ、関数が呼ばれている間のみ有効となります(その仕組についてはエンジョイCの範疇ですので割愛します)。ユーザが書いたローカル変数を操作するコードはスタックを指すベースレジスタとスタックポインタを基準に場所がきまります。これを pic.twitter.com/MtvYLV6PfT

2020-11-16 01:59:32
拡大
ほえほえ@スプシマン @hoehoe1234

「スタックフレーム」と呼びます。関数呼び出しが積み重なった時に、仮に、自分自身を再度呼び出してもローカル変数は「その呼出固有の値」となるのは関数呼び出しのたびにこのスタックフレームが重なり、そのスタックフレームの中にローカル変数が確保されているからです。ですから、

2020-11-16 02:01:00
ほえほえ@スプシマン @hoehoe1234

関数呼び出しが終了すると(今の)スタックフレームが消滅しますのでローカル変数はなくなります。 VBAではCTL+Lで関数呼び出し階層が表示できます。このとき、呼び出し階層の中の任意の関数を指定して移動できます。この機能は強力です。関数呼び出しを見るだけでなく、関数呼び出しが行われている

2020-11-16 02:02:42
ほえほえ@スプシマン @hoehoe1234

各スタックフレーム中のローカル変数の値を見ることができます。言葉を変えると、呼び出した関数側のローカル変数をみることができるのです。これは強力です。VBAデバックにおいて最大の武器の一つと言えます。たとえば実行時例外が発生した場合はその場でとまりますが、そこでCTL+Lを押すことにより、

2020-11-16 02:04:25
ほえほえ@スプシマン @hoehoe1234

最終的に例外を発生した関数までの関数呼び出しを直接みて、かつ、その各階層で変数を確認することができます。(アプリは止まりますが)ログを取得するよりも遥かに強力な機能です。ノンプロアプリでは下手にエラー処理をするよりも例外処理をせずにアプリを止めておけ。というのはこのあたりのこと

2020-11-16 02:05:52
ほえほえ@スプシマン @hoehoe1234

を指しています(当然ですが業務アプリはエラーに対する考え方が別です。あくまでノンプロアプリの方針です)。 話がそれてしまいました。メモリの話にもどります。ローカル変数は関す呼び出しに応じてスタックフレームという単位でメモリ上に積み重なって確保されます。同じ関数が複数回

2020-11-16 02:07:45
ほえほえ@スプシマン @hoehoe1234

呼び出されたとしてもそれぞの関数は固有のローカル変数を持つことになります。②のデータセグメントはわかりやすいですね。静的変数領域とも呼ばれていてVBAではモジュール変数がこれに該当します。プログラムが起動されたときに最初から用意されている変数ですね。ですので(可視であれば)、

2020-11-16 02:10:09
ほえほえ@スプシマン @hoehoe1234

どの関数からも操作が可能となります。VBAではグローバル変数とモジュール変数のメモリ上の違いは実質ありません。モジュール変数がそのモジュール以外からも見えたときにはグローバル変数と呼ぶような感じでしょうか。一番わかりやすいタイプの変数だと思います。

2020-11-16 02:13:29
ほえほえ@スプシマン @hoehoe1234

③のヒープ領域は、データセグメントを拡張して取得することができます。これは動的メモリ確保とも呼ばれています。どうしてこのような仕組みが必要になるのでしょうか?最初からデータセグメントを目一杯確保しておけばいいのでは?とおもわれるかもしれません。

2020-11-16 02:15:07
ほえほえ@スプシマン @hoehoe1234

でも使わないメモリを予め確保するのはメモリ効率がわるいですね。なのでアプリケーションの要求に応じてOSが必要なだけ追加メモリを割り当てるしくみがあります。VBAではこれはどのような状況の時に発生するでしょうか?そうですね。オブジェクトをNewしたときが典型的に必要になりそうですね。

2020-11-16 02:17:30
ほえほえ@スプシマン @hoehoe1234

オブジェクトをNewして生成したインスタンスはいくつ作成されるかわかりませんので動的にメモリ領域(以下単に領域)を確保したほうがよさそうですね。あとは確証はありませんが文字列、配列等も動的にメモリを確保していると思われます。

2020-11-16 02:18:54
ほえほえ@スプシマン @hoehoe1234

今回、オブジェクト変数にバインドされる(インスタンスがNewの呼び出してヒープ上に生成され、参照型変数(オブジェクト型変数)に参照が代入されることをバインドといいます)インスタンスはヒープ上に生成され、通常はこれがローカル変数(すなわちスタック上の変数)にバインドされます。

2020-11-16 02:20:39
ほえほえ@スプシマン @hoehoe1234

これが図左下となります。スタックフレーム上のローカル変数がヒープ上の生成されたインスタンスへの参照を保持するイメージです。インスタンスを参照しているローカル変数は、関数の呼び出しが終了すると消滅しますが、それはヒープ上のインスタンスへの参照がなくなるだけで、

2020-11-16 02:22:59
ほえほえ@スプシマン @hoehoe1234

ヒープ上のインスタンス自体はなくなりません。ではインスタンスはいつなくなるのでしょうか?これはガベージコレクションと言われる仕組みで各プログラミング言語で異なりますが、一般的には、ユーザコードからインスタンスへの参照がなくなった時点でシステム側(VBランタイム)が自動で開放します。

2020-11-16 02:24:09
ほえほえ@スプシマン @hoehoe1234

なので、特定の関数からの参照がなくなったとしても、他の関数(呼び出し階層が下の関数)、またはモジュール変数が参照を保有していればそのインスタンスは開放されません。あくまでもユーザコードから到達できなくなった時点で開放されます。 pic.twitter.com/N9osQmnyNZ

2020-11-16 02:26:09
拡大
ほえほえ@スプシマン @hoehoe1234

オブジェクトとインスタンスの違いはなにか?については、当塾ではオブジェクトはインスタンスを含む広い概念と定義しています。一方、インスタンスはメモリ上に自分が明示的にNewをして確保したもの。という定義にしています。もちろん、ブレはありますが大まかには自分が生成したもをインスタンスと pic.twitter.com/cLFVa4QHDy

2020-11-16 02:28:37
拡大
ほえほえ@スプシマン @hoehoe1234

呼んでいます。このあたりは呼び方自体にはあまり拘る必要はなく、概念をしっかり理解しておけばよいと思います。繰り返しになりますが、ヒープ領域とはデータセグメントの動的に拡張された部分ということができます。主な用途はVBAではインスタンスの生成される場所ということになります。

2020-11-16 02:30:33
ほえほえ@スプシマン @hoehoe1234

最後に④のテキストセグメントとなります。この領域はプログラムのコードそのものとなります。通常、読み込み専用にOSにより設定されています。この部分は実行するべき機械語(もしくはVMの実行コード、VBAではPコードと呼ばれるもの)そのものが書き込まれています。

2020-11-16 02:32:55
ほえほえ@スプシマン @hoehoe1234

(補足)このような仕組みは一般的に実行ファイルといわれるOSが直接実行する仕組みの話をベースにしてます。VBAはスクリプト言語ですのでOSとの間に共通の実行システムが存在しています。ですから一連のツイは、「一般的にはメモリはこのようになっている」というようにご理解ください。

2020-11-16 02:35:36
ほえほえ@スプシマン @hoehoe1234

VBAでのコレクションってなんでしょうか?静的型言語ではクラスまたはインタフェースにより型が確定します。コレクションは「コレクション」という型もしくは「データを保管する一連の仕組み」の両方を指しますので用語の使い方が難しい場合があります。 pic.twitter.com/M8JU3328yV

2020-11-16 02:37:29
拡大
ほえほえ@スプシマン @hoehoe1234

VBAではWorkbooksのような複数形のオブジェクト、Range、Collection型とあり、なにがオブジェクトでなにがコレクションなのかいまいち判然としません。逆に言うとこれらをきちんと区別する必要がないとも言えます。とはいえ、一般的には次のメソッドを保有するオブジェクトをコレクションと

2020-11-16 02:40:22