c#関数とメモリ消費

このQ&Aのポイント
  • c#の関数はオブジェクトごとにメモリを消費するのか
  • 関数のポインタによるメモリ消費について
  • c#で関数を増やしてもメモリ消費は変わらないのか
回答を見る
  • ベストアンサー

c# 関数とメモリ消費

 こんにちは、c#初心者です。  自分は文字通りc#をやっているのですが、先輩がc++をなさっていて、その先輩が言うには「(特にvirtual, abstractの)静的でない関数はメンバ変数と同じようにオブジェクトごとにメモリを消費する」というのです。  関数に対するポインタかそれに近いものを持っているらしいのですが、あるクラスでフィールドを増やすと初期化にかかる時間が増えましたが、関数を増やしても時間は変わりませんでした。  そのため(こんな方法で確かめられるのか分かりませんが)本当に関数がインスタンス毎にメモリを消費するのか気になっています。  どなたか詳しい方がいらっしゃいましたらご意見を伺わせてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • nas02
  • ベストアンサー率70% (22/31)
回答No.1

koumei000さん、こんにちは。 参考URLの記事を一読されたら、質問内容が分かると思います。 恥ずかしながらこの記事を読むまでは、貴殿の先輩と同様の事を 思い込んでいましたが、C++も含めオブジェクトの考え方はこうなのでは ないかと思います。

参考URL:
http://blogs.msdn.com/b/nakama/archive/2008/12/18/9231090.aspx
koumei000
質問者

お礼

 一時期どっちなのかと迷っていたこともあったのですが、速度測定をして、「インスタンスごとに関数が生成されていればその分オーバーヘッドが大きくなるはず」、という予測で、結果が速度変化なしだったので「きっとくらすごとにもっているだけなんだ」と思っていたのですが、やっぱり先輩に言われるとぐらつきますよね。  これですっきりしました。ありがとうございます。

その他の回答 (1)

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

たぶんvtableの事だと思いますけど、vtableそのものはインスタンス毎に用意する必要はないのでメソッド増やしたところで増えるのはクラス単位だと思いますよ。

koumei000
質問者

お礼

 そうです。仮想関数テーブルがそれなりに大きくなるとか言っていました。  それでもやっぱりクラス単位なんですね。安心しました。

関連するQ&A

  • 関数で値渡しと参照渡しではどっちがメモリを使うのか

    クラスAの大きなサイズのオブジェクトを、 クラスBで処理するメソッドを書こうとしています。 ◆質問 このとき、クラスBでは、byval で記載するのと、byrefで記載するのでは、 どちらの方がメモリを食わないのでしょうか? ◆自分の想定 (1)byrefで記載した場合、そのオブジェクトのポインタを受け取って処理するため、あんまりメモリは食わない。 (2)byvalで記載した場合、ある意味、.clone のような処理がされて、渡されたオブジェクトと同じサイズのメモリを食う? ※処理しようとしていることは、特に参照渡しされた変数の値を修正するような類ではないです。 なので、「オブジェクトを不用意にいじってしまう危険性」などの観点は無視し、メモリの観点の話です。 ちなみに、メソッドを、shareで宣言しようが、インスタンス化してからじゃないと使えないように宣言しようが、その関数のために使用されるメモリのサイズ(※クラスBのインスタンス化のためのメモリではないという意味)は変わらないということで合っていますでしょうか? .

  • C++の文法で分からないことがあります

    C++のコードを解析しているときに分からない部分が出てきたので教えていただきたいのですが... あるクラスのメンバ関数の引数で( {オブジェクト名}*& {変数名} )とあったのですが, *& てなんでしょうか? 参照へのポインタという意味かなとは思うのですがそれはそれで意味が分からないし、これを使うことでどんなことが起こるのか分かりません。 どなたか知っている方教えてください。 あと、objective-c++のリファレンスって存在するのでしょうか?あったらどこにあるのか教えてくださると非常に助かります。 よろしくお願いします。

    • 締切済み
    • Mac
  • フィールド、インスタンス変数、プロパティ、…

    フィールド、インスタンス変数、プロパティ、… C++では、クラスの構成要素はメンバと呼ばれ、メンバには変数と関数と二種類あり、変数は、 (1)メンバ変数(オブジェクトがデータを保持するメンバである事を強調する為、別称データメンバ) 関数は、 (2)メンバ関数 と、とってもクリアに呼ばれていました。 ところがJavaになって、メンバ変数が (1’)フィールド メンバ関数が (2’)メソッド と呼ばれるようになりました。 さらに(1’)が、 (1’’)インスタンス変数 (1’’’)プロパティ という風にも呼ばれるようになり、(1')と(1'')と(1''')が、混同して呼ばれるようになりました。 多くの人は、 「それらは "interchangeable" で同じ意味で用いられるものなのだ」 という根拠がよくわからない『解説』をしますが、同じ意味ならば同じ用語を使った方が全体がスッキリ且つ正確に表現できて都合がいいのに、なんでいろいろな用語を混用するのでしょうか? (A)そもそも何でデータメンバをフィールドと言い換えたのか?  (a)データメンバの方が、それがデータであることを示唆していていいのでは?  (b)フィールドって、Cの構造体のフィールドから名前が由来しているのでしょうか? (A)何でわざわざ(1'')や(1''')みたいな用語を使うのか? (B)どういう意図でそういう用語を使うのか? そこら辺の事情に詳しい方がいらっしゃいましたら、お教えください。

    • ベストアンサー
    • Java
  • 【C++】クラス内のメンバ関数の占める領域

    C++のことです(恐らく、他言語にも共通していると思いますが)。 例えば、 class a { void func(); }; という風なクラスがあったとして、これを a kurasu[100]; と言う風にインスタンスを生成した場合、メンバ関数funcも100個分作られるのでしょうか。 “関数が作られる”って言い方は適切でないかもしれませんが……。。。 100個分の関数用にメモリが割り当てられるのか、といったニュアンスです。 よろしくお願いします。

  • マルチスレッド下でのインスタンス変数・クラス変数

    よろしくお願いします。  マルチスレッド下で動作するクラスを作成しています。データにアクセスするためのオブジェクトを クラスのフィールド値として保持し、使い回しを行いたいと考えています。このデータアクセスオブジェクト(以下Dao)内では特にフィールドは使用せず、全てローカル変数のみで動作するようになっています。Dao自体は初回のクラス生成時にstatic処理にてフィールドにセットされます。  このDaoを保持するフィールドは、staticなクラス変数が良いのか、インスタンス変数として保持する方が良いのか迷っております。  クラス変数ならばPermanent領域をオブジェクト1つ分のメモリ使用で済み、インスタンス変数だとスレッド毎にheapを使い、処理数が増えるとメモリ圧迫しちゃう?と安易に考えてしまったりしています。  ご意見・ご助言よろしくお願い致します。

    • ベストアンサー
    • Java
  • 【C++】関数のアドレス

    Aクラスの持つ、 メンバーxのアドレスが100番地で、関数yのアドレスが200番地のとき、 (イメージ図「■■■■■■■■■■★★★★★★★★★★」)         ↑この辺が100番地  ↑この辺が200番地 Aクラスのポインタ型に、 Aクラスを継承したChildBクラス(関数zを持つ)を格納したら、 ChildBクラスの関数zの格納される場所って、確保できないはずでは?と思っていましたが、 実際にソースを書いてみると、普通にコンパイルも通って、普通に実行もできますよね。 なぜなのでしょうか? 下のように認識しているのですが、どの辺の理解が間違っているのでしょうか? (イメージ図「■■■■■■■■■■★★★★★★★★★★」)         ↑クラスAのポインタには、■10個と★10個の分しかメモリを確保しないはず。         しかし、実際に関数zを動作させることができているのが不思議です。 というのは、クラスAをインスタンス化するのに100バイト必要だったとして、 色んな拡張をしたChildBクラスは、300バイト必要な状況だったなら、 100バイトしかない、「クラスA」には格納しきれないのでは?と感じたのです。 仮に、ポインタ型が、各プロパティや各関数の格納先の「アドレスの先頭」だけを格納していたとしても、 クラスAには存在しない、関数zの「アドレスの先頭」を格納するための領域そのものがないはずなのでは?と捉えているのです。 動いている以上、私の認識のどこかしらが間違っているというのはわかるのですが、 どの辺を誤解してしまっているのでしょうか? .

  • 継承・実装の関係で悩んでいます。

    継承・実装の関係について悩んでいます。 ここでは、アクセス制御を考えずに、インスタンスかstaticかabstract(ここではabstract final staticやabstract classのこと)の違いで、どう継承するのか考えています。 // 継承 はメソッドのオーバーライドのことを考えます。(オーバーロードは考えない) クラスAからクラスBでオーバーライドしたメソッドは、 クラスCでさらにオーバーライドできるのでしょうか? クラスCが クラスBのクラスAからオーバーライドしたメソッド をクラスBのメソッドとして見たときに、オーバーライドすることは可能なのでしょうか? クラスA │ インスタンスフィールドA │ staticフィールドA │ │ クラスA() { } │ │ インスタンスメソッドA () { } │ staticメソッドB() { } ↓ クラスB extends クラスA │ インスタンスフィールドA // 継承 │ インスタンスフィールドB │ staticフィールドB │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ インスタンスメソッドA () { } // 継承 │ │ インスタンスメソッドB () { } │ staticメソッドB () { } ↓ クラスC extends クラスB implements インタフェースD, ... ↑ インスタンスフィールドA // クラスBのフィールドを継承 │ インスタンスフィールドB // クラスBのフィールドを継承 │ インスタンスフィールドC │ staticフィールドC │ │ サブクラス2() { } │ │ インスタンスメソッドA () { } // クラスBのメソッドを継承 │ インスタンスメソッドB () { } // クラスBのメソッドを継承 │ インスタンスメソッドD () { } // インタフェースDのメソッドを実装 │ インスタンスメソッドE () { } // インタフェースDのメソッドを実装 │ │ │ インスタンスメソッドC () { } │ staticメソッドC() { } │ interface インタフェースD extends インタフェースE ↑ │ staticフィールドD // public static final │ │ インスタンスメソッドD() { } // public abstract │ インスタンスメソッドE() { } // 継承 │ interface インタフェースE staticフィールドE // public static final インスタンスメソッドE() { } // public abstract

    • ベストアンサー
    • Java
  • C#のdelegateをC++とjavaで?

    C#のデリゲードを javaとC++でできないでしょうか。 ただし、質問内容を勘違いされそうなので、求めている内容と、 求めていない内容を、詳しく 書きますと。 インタフェース委譲を使った例は、求めていません。 あらかじめ、委譲先に静的に仕組みを 作っておかなく手も、C#のデリゲードのように、シグニチァが同じなら 委譲先をはめ込めれるのが欲しいです。 単なる関数ポインタの例は、求めて いません。 C#でdelegate型を引数にとる ところに、あるインスタンスの メソッドを渡すと。 どのインスタンスのどのメソッドかまで、 認識して、コールバックできます。 関数ポインタでは、これができない。 STLの関数オブジェクトとか、古い感じの情報にヒントがあるか。調べてみましたが。よくわかりませんでした。 結局、この関数オブジェクトは、僕が求めているモノとは、違うような気がします。 よくわかりませんが。 欲しいのは、どのインスタンスのどのメソッドかまでを特定して、 記憶できる型をどうやって javaや、C++で実装できるか。 それをインタフェース委譲のように、 委譲先にあらかじめ、仕込んでおくことなしに。 ただ、メソッドのシグニチァが同じであるだけで、どのインスタンスのどのメソッドかまでを特定して記憶できる C#のデリゲードのような型を。 特殊なコンポーネントを利用せず。 標準的な言語構文のみをつかって、 どのようにしたら、 javaや、C++で、実装できるか? です。 詳しい方が、いらっしゃいましたら、 教えてください。

  • C++のnewで確保した領域について

    こんにちわ。C++を勉強し始めた者です。 new演算子を使ってインスタンスを生成した場合、それはスタックではなくヒープ領域に確保され、不要になったらdeleteを使って領域を解放しなければいけない認識です。 C++の初心者向けサンプルコードを見ていて疑問があったので質問させてください。 (例)クラスA.cpp ======================== #include <Car> #include <Garage> ~略~ クラスAのコンストラクタ{ Car *mycar = new Car("プリウス"); addGarage( mycar ); } クラスAのデストラクタ{ } ======================== 上記のような実装のクラスAがあったのですが、コンストラクタでCarクラスのインスタンス生成をして、オート変数の*mycarに格納して、Garageの公開関数に渡しています。 質問1:このクラスAをインスタンス生成した場合、コンストラクタで確保したヒープ領域は、プログラム終了時まで解放されない認識であっていますか? 質問2:オート変数の*mycarはコンストラクタからreturnした時点で解放されてしまうので、今のままではデストラクタでヒープ領域をdeleteできない認識であっていますか? 質問3:newで生成したインスタンスへのポインタは、その関数内でdeleteしない場合、メンバ変数やstatic変数、グローバル変数に格納しなければdeleteできなくなるという理解であっていますか? 質問4:C++のコードでnewした戻り値をオート変数に格納するプログラムは通常使うことはあるのですか?

  • C言語のメモリ領域確保

    ポインタ変数ををmain関数で宣言し、関数test()にて必要分だけ領域確保してそのアドレスをmain関数のポインタ変数に渡して利用することは可能でしょうか。 (サイズのわからないテキストデータを、十分に大きな配列に入れるのではなく、関数でメモリを動的確保して無駄の無い配列に入れたい等) C言語ではやはり無理で、構造体のリストにするのが一番でしょうか。 初歩的なことで申し訳ありませんがどなたかお願いいたします。

専門家に質問してみよう