Far*_*ran 6 memory-management common-lisp clos
有没有办法找出一般的类或基本数据类型的实例使用了多少内存?
我在cl中有一个玩具webframework,它创建和管理带有代表html标签及其属性的类实例的网页,并且因为它们应该创建一个html页面,所以他们在名为children的插槽中有子节点.所以我想如果采用这种方法,用户会话将花费多少服务器.谢谢.
据我所知,标准中的任意对象都没有这样的东西,但是有依赖ccl:object-direct-size于实现的解决方案,比如在CCL中:
CL-USER> (object-direct-size "foo")
16
Run Code Online (Sandbox Code Playgroud)
但是,请注意这些是否符合您的要求取决于"大小"的含义,因为这些函数通常不包括对象引用的组件的大小.您还可以运行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
Run Code Online (Sandbox Code Playgroud)
也许你可以试试这样的东西(未经测试,真的只是一个快速的黑客):
(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))
Run Code Online (Sandbox Code Playgroud)
例如:
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
Run Code Online (Sandbox Code Playgroud)
在Common Lisp中,CLOS对象通常是插槽的集合.通常,这些槽可以在内部存储在某种矢量中.CLOS槽通常包含指向某个数据对象的指针,或者对于一些原始数据类型,可能包含数据本身.这些原始数据类型必须适合内存字:例如fixnums和characters.Common Lisp实现通常不会将更复杂的数据结构内联到插槽中.例如,可以声明一个槽包含一个fixnums向量.实现不会在CLOS对象中分配此向量.CLOS对象将指向矢量对象.
CLOS对象本身应该占用:槽数*字大小+开销.
假设一个字长4个字节,32位.
这可能是具有十个插槽的CLOS对象的大小:
10 slots * 4 bytes + 8 bytes = 48 bytes
Run Code Online (Sandbox Code Playgroud)
现在假设CLOS对象的每个槽指向不同的字符串,每个字符串长100个字节.
上面的例子:
1 CLOS object + 10 strings each 100 bytes.
48 bytes + 10 * 100 = 1048 bytes
Run Code Online (Sandbox Code Playgroud)
现在想象每个插槽指向相同的字符串:
1 CLOS object + 1 string of 100 bytes.
48 bytes + 100 bytes = 148 bytes
Run Code Online (Sandbox Code Playgroud)
要计算CLOS对象的大小,您可以:
只计算CLOS对象本身的大小.这很简单.
以某种方式计算可从对象到达的对象的图形,确定唯一的存储器对象(减去直接分配的基元对象)并对这些对象的所有存储器大小求和.
| 归档时间: |
|
| 查看次数: |
2071 次 |
| 最近记录: |