静的型付と動的型付のメモリの動きを理解したい。
私は本格的にはPythonしか触れた事が無いのですが、
私はPythonを学んだ時、静的型付けと動的型付けを以下のように考えていました。
静的型付言語・・・型宣言をしなくちゃ駄目。
動的型付言語・・・型宣言をしなくてもOK.
これでもプログラムを組むには何ら支障はありませんでした。
だけど、最近さすがにそれじゃいけないだろうと思うようになりました。そのため、自分なりに考えを整理してみる事にしました。
不十分な理解を承知の上で、私の頭の中に、以下のように定めて行きます。
wikipedia によると、
静的型付言語・・・コンパイル(プログラム実行)前に変数の型が決定されている。
動的型付言語・・・コンパイル(プログラム実行)後に変数の型が決定される。
静的型付言語の場合、プログラム実行中に型が変更されることはないとします。
それぞれの変数のアドレスがメモリに割り当てられる。
そしてプログラムが終了するまで、このメモリは解放されないとします。
しかし、プログラマが、メモリを解放する処理を明示的に行った場合は別とします。
動的型付言語の場合、プログラム実行中に型が変更されるので、その都度型が調べられ、
適当な型がその変数に割り当てられるとします。
(動的型付言語は、この決定のためのプロセスに時間がかかり、処理速度が遅くなる最も大きな原因となる。)
もしその変数が別の型の値が入れば、その型に上書きされる。Python
の場合、s
(str
型)という変数を、i
(int
型)という変数に代入すると、i
はstr
型となる。
元々のi
という変数には、s
のメモリが割り当てられ、元々iのあるアドレスは解放される。
i = 0;s = "a";
i is a;-False
i = s
i is a;-True
i;-"a"
メモリ解放のプロセスは、言語側が自動で行ってくれており、プログラマが行わなくてもいい。
静的型付言語だと、このような事は出来ないとします。
極端に言えば、静的型付言語と、動的型付言語は、どんな場合でも、このように変数の型が定まるものであるとします。
頭の中で、このように動的型付言語と、静的型付言語を整理したとします。
しかし、静的型付言語であるJava
では、強制型変換が行われます。また、自動型変換という機能もあります。
この静的型付言語であるはずのJava
で、メモリが割り当てられているのに、強制的に型が変換されるとすれば、メモリの動きはどのようになるのでしょうか。(強制)という言葉は、解放プロセスもなく、無理やりというニュアンスに思えます。
型が変換された後の型になるのはわかります。しかし、メモリの動きはいったいどうなっているんでしょうか?メモリはのっぺらな配列であると聞きます。そして、静的型付けの場合、最初に割り当てられたアドレスがギュッと詰まっているとします。その時、その中のアドレスの一部が強制的に書き換えられたとき、もし元の領域よりも大きな領域が割り当てられれば、それは何らかのエラーを発生させるのでしょうか?(別の領域と被ると思うからです。)それとも、元のアドレス自体は一旦解放され、新しく別の領域にメモリが割り当てられるのでしょうか?それとも、被ると思われるアドレスを、そのまま大きくなった分だけスライドさせるのでしょうか?元々そんなに詰めた形では割り当てられていないのでしょうか?
いずれにせよ、このような事が可能であるとするならば、静的型付言語の中にも、動的型付と言える部分があるんだなと感じます。
メモリにはスタックと、ヒープというのがあり、スタックは整列的。ヒープはランダム的に割り当てられると言います。静的型付言語だとしても、この二つを使い分けて移し合いながらメモリの動的管理を行っているのでしょうか?
とすれば、スタックとヒープ両方のメモリが満杯になった時に、なおメモリの領域を要求する時に起るエラーが、スタック・オーバーフローと考えてもよろしいでしょうか?
wikipediaによると、結局静的型付と動的型付の境界線は曖昧だ。と知りました。
動的型付の場合は、メモリの解放を自動で行ってくれるため、楽ですし、また任意の場所に割り当てればよいと思いますが、静的型付けの場合、これはプログラマが解放と割り当ての責任を負う。という認識で間違いないでしょうか?
何個も聞いてるので、まとめます。(さりげなく項目が増えています。)
・静的型付言語でも、動的型付が行われれば、メモリはどのように動くのでしょうか。
・スタックとヒープを使い分けて、メモリの動的管理をしているのですか?
・スタックとヒープ両方の領域が詰まっていてなおメモリの領域を確保しようとすると、スタック・オーバーフローというエラーが起きるのですか?
・静的型付言語の場合、元々静的に割り当てられていたメモリを解放して、別のメモリを割り当てるのは、ユーザーの責任によって管理するもので、動的型付け言語ではない場合は、全てそのようになりますか?(c
のmalloc
関数というのをよく聞きます。)
・実は言語ごとに異なり、結局のところ、その都度メモリについての扱いを変えるしかないでしょうか。
・私の頭の中に敷いた理解自体に、どこかおかしいところはありますか?
・もう少しC
やC++
などに触れてから出直すべきですか?