memory usage by objects in common lisp

后端 未结 3 1922
伪装坚强ぢ
伪装坚强ぢ 2021-01-18 01:15

Is there a way to find out how much memory is used by an instance of a class or basic data types in general?

I have a toy webframework in cl that creates and manage

3条回答
  •  独厮守ぢ
    2021-01-18 02:00

    As far as I know, there is nothing like this for arbitrary objects in the standard, but there are implementation-dependent solutions, like ccl:object-direct-size in CCL:

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

    However, be aware that whether these do what you want depends on what you mean by "size", since those functions usually don't include the size of the components the object references. You can also run the GC, initialize a few objects and compare room's output before and afterwards.

    Also, note that time usually includes allocation information:

    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
    

    Maybe you could try something like this (untested, really just a quick hack):

    (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))
    

    For example:

    CL-USER> (defclass foo ()
               ((child :accessor child :initarg :child)))
    #
    CL-USER> (defclass bar (foo)
               ((child2 :accessor child2 :initarg :child2)))
    #
    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
    

提交回复
热议问题