8

クラスのインスタンスまたは一般的な基本データ型によって使用されているメモリの量を確認する方法はありますか?

私はclにおもちゃのウェブフレームワークを持っています。これはhtmlタグとそのプロパティを表すクラスのインスタンスでウェブページを作成および管理します。彼らはhtmlページを作成することになっているので、子と呼ばれるスロットに子があります。そのため、このアプローチを採用した場合、ユーザーのセッションにサーバーのコストがかかることを考えていました。ありがとう。

4

3 に答える 3

7

私の知る限り、標準の任意のオブジェクトにはこのようなものはありませんがccl:object-direct-size、CCLのように実装に依存するソリューションがあります。

CL-USER> (object-direct-size "foo")
16

ただし、これらの関数には通常、オブジェクトが参照するコンポーネントのサイズが含まれていないため、これらが目的の機能を実行するかどうかは、「サイズ」の意味によって異なることに注意してください。また、GCを実行し、いくつかのオブジェクトを初期化し、前後の出力を比較することもできます。 room

timeまた、通常、割り当て情報が含まれていることに注意してください。

CL-USER> (time (length (make-array 100000)))
(LENGTH (MAKE-ARRAY 100000))
took 0 milliseconds (0.000 seconds) to run.
During that period, and with 2 available CPU cores,
     0 milliseconds (0.000 seconds) were spent in user mode
     0 milliseconds (0.000 seconds) were spent in system mode
 400,040 bytes of memory allocated.
100000

たぶん、あなたはこのようなことを試すことができます(テストされていない、本当に簡単なハック):

(defmethod size ((object standard-object))
  (let ((size (ccl:object-direct-size object)))
    (dolist (slot (mapcar #'ccl:slot-definition-name
                          (ccl:class-slots (class-of object))))
      (when (slot-boundp object slot)
        (incf size (size (slot-value object slot)))))
    size))

(defmethod size ((list list))
  (reduce (lambda (acc object) (+ acc (size object)))
          list
          :initial-value (ccl:object-direct-size list)))

(defmethod size (object)
  (ccl:object-direct-size object))

例えば:

CL-USER> (defclass foo ()
           ((child :accessor child :initarg :child)))
#<STANDARD-CLASS FOO>
CL-USER> (defclass bar (foo)
           ((child2 :accessor child2 :initarg :child2)))
#<STANDARD-CLASS BAR>
CL-USER> (size '())
0
CL-USER> (size "foo")
16
CL-USER> (size '("foo" "bar"))
40
CL-USER> (size (make-instance 'foo))
16
CL-USER> (size (make-instance 'foo :child '("foo" "bar" "baz")))
72
CL-USER> (size (make-instance
                'bar
                :child "foo"
                :child2 (make-instance 'foo :child (make-array 100))))
456
于 2012-09-01T20:27:04.673 に答える
6

Common Lispでは、CLOSオブジェクトは通常スロットのコレクションです。通常、これらのスロットは、ある種のベクトルに内部的に格納されている可能性があります。CLOSスロットには通常、データオブジェクトへのポインタが含まれるか、いくつかのプリミティブデータ型の場合はデータ自体が含まれる場合があります。これらのプリミティブデータ型はメモリワードに収まる必要があります。例としては、fixnumと文字があります。Common Lispの実装は通常、より複雑なデータ構造をスロットにインライン化しません。たとえば、スロットにfixnumのベクトルを含めるように宣言できます。実装は、CLOSオブジェクト内にこのベクトルを割り当てません。CLOSオブジェクトはベクトルオブジェクトを指します。

その場合、CLOSオブジェクト自体が占有する必要があります:スロット数*ワードサイズ+オーバーヘッド。

ワードの長さが4バイト、32ビットであると仮定します。

これは、10個のスロットを持つCLOSオブジェクトのサイズである可能性があります。

10 slots * 4 bytes + 8 bytes = 48 bytes

ここで、CLOSオブジェクトの各スロットが異なる文字列を指し、各文字列の長さが100バイトであると想像してください。

上からの例:

1 CLOS object + 10 strings each 100 bytes.

48 bytes + 10 * 100 = 1048 bytes

ここで、各スロットが同じ文字列を指していると想像してください。

1 CLOS object + 1 string of 100 bytes.

48 bytes + 100 bytes = 148 bytes

CLOSオブジェクトのサイズを計算するには、次のいずれかを実行できます。

  • CLOSオブジェクト自体のサイズを数えるだけです。簡単だ。

  • どういうわけか、オブジェクトから到達可能なオブジェクトのグラフを計算し、一意のメモリオブジェクト(直接割り当てられたプリミティブオブジェクトを差し引いたもの)を決定し、それらのすべてのメモリサイズを合計します。

于 2012-09-02T09:34:17.407 に答える
2

私もclにWebフレームワークを持っており、同じセッションの問題に苦しんでいました。これがユニバースから送られてきたものですhttps://people.gnome.org/~xan/memory.lispsbcl で機能しているようです

(memory::dump-memory (weblocks::active-sessions))
Total memory used: 99.785706 MB
于 2014-12-07T03:28:08.783 に答える