如何获取对象变量所占字节数?【100分】
我们定义了一个对象变量
比如
dim obj as object
然后
set obj=creatobject("test.test")
然后做一些操作,插入数据,赋值之类的
接下来,如何获取这个obj到底占用了多少字节的内存呢?
[解决办法]
Option Explicit
Dim mXlsApp As Excel.Application '应用
Dim mXlsBook As Excel.Workbook '工作薄
Dim mXlsSheet As Excel.Worksheet '工作表
Private Sub Command1_Click()
Set mXlsApp = New Excel.Application
Set mXlsBook = mXlsApp.Workbooks.Open("c:\book1.xls")
Set mXlsSheet = mXlsBook.Worksheets(1)
Debug.Print LenB(mXlsApp)'我的电脑显示是30个字节
' 以下代码读取Excel中图表到图片框
mXlsSheet.ChartObjects(1).Chart.CopyPicture '读取图表到剪贴板
Picture1.Picture = Clipboard.GetData '粘贴数据到图片框
Clipboard.Clear '清除剪贴板数据
mXlsBook.Close
mXlsApp.Quit
Set mXlsSheet = Nothing
Set mXlsBook = Nothing
Set mXlsApp = Nothing
End Sub
[解决办法]
LenB可行
[解决办法]
Object永远为4字节,保存的是实际对象的地址,lenB(obj)可得到对象的结构大小,从技术上说,系统是无法确定一个对象实际所占的字节数的,要得到实际大小,只能依靠对象本身
[解决办法]
要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)
你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。
[解决办法]
[解决办法]
- VB code
Option ExplicitPrivate Sub Command1_Click() Dim objP As Variant objP = "adkd" Debug.Print LenB(objP) Set objP = Nothing Debug.Print LenB(objP)End Sub
[解决办法]
这是做不到的。
比如你是老板,雇了一名员工,虽然你发工资给该员工,也无法确切知道该员工的个人资产是多少。
该员工有自己的房产、现金,还有欠别人的钱,也有借给别人的钱,许多都属于隐私,你无法知道的。
同样一个被你调用的对象,你也无法知道它的内存耗用,光看进程的内存增长也没用,有些增长的内存并不属于该对象。
[解决办法]
这主要和编译器和对象的类型有关
对于一个简单的vb类,我倒是可以数出来具体用了多少内存,但意义不大
你的问题其实是vb的根本症结,如果这个长度知道了,也就能实现vb的对象继承了
[解决办法]
继承和内存没关系。
VB 和 VC 都用对象指针,却在继承的支持上有所不同。
只要用指针的语言(包括 .Net),就不需要关心对象精确的内存占用。
只需要按照数据量估算一下大概的内存耗用,然后选择恰当的数据结构就可以了。
[解决办法]
继承需要复制副本,复制副本即复制内存,复制内存即需要复制长度及起始地址或称指针
单纯的指针作用,是引用,而且真正意义上的继承,vb中惯用的方法就是引用,因为单纯的vb没有直接的继承方法,com对象包括继承,vb的对象则不可实现继承,所以有人说vb非面向对象的编程语言
对于对象的继承,估算?。。。。
[解决办法]
和继承这些应该没多大关系,C++可继承,但C++也无法计算一个对象所占内存,根本原因在于,机器无法区分对象的一个long成员到底是一个数值还是一个指向其它结构的指针,纵算做到了区分,那这个指针指向的结构的大小怎么算?这个结构中又有指向其它结构的指针,还有这些二级、三级指针。。。可能又指向上层结构,在一个稍有规模的系统中,所有对象岂不是构成一张巨大的网图?光遍历这张图现有机器都够呛了,还有时间做其它事?
[解决办法]
简单来说, 继承就是复制一个 实例化 对象A 的副本
复制副本就必然要复制内存, 如果没有指针(复制的起始位置) 和 长度(对象数据) 怎么实现复制?
一个对象, 一般就说类这个东西, 到底是什么样? 他的数据不是抽象的放在内存中哪哪都是一堆,或者一坨东西....
他是有组织, 有纪律, 有文化, 有素质的紧密且连续顺序的排列在一个堆上, vb中,一个不含任何成员或数据的对象至少包括28 bytes数据, 多一个 private 变量则多 4 字节,一个public 类型变量则至少是4字节,通常是 8字节, 对象的数据可以想象为一个结构体, 一个容纳了全部对象成员的结构, 继承或者说复制这个对象, 就是复制这个结构, 还有一些基础知识不再解释...
以上内容, 可供观赏...
[解决办法]
有组织, 有纪律, 有文化, 有素质是真的,紧密且连续顺序的排列就不一定了,最简单的指针链表还真就有可能这是一堆,哪是一坨;如果不知道节点数目或者结束标志,根本无法计算这个链表的长度,而这两点对象外的东西是很难知道的;
不是对象所占内存不能精确计算,而是实现的机制上不太可能由对象外的东西计算;
复制副本根本不是个问题,只要每个对象都能遵守一定规则,对外提供计算长度、复制自身等方法即可,比如一些常见的C++或C#对象的Clone,Ado对象的Clone
最后顺便,VB6其实也有继承,只不过不是基于类,而是基于接口而己
[解决办法]
...............
书中自有颜如玉... 书中自有黄金屋... 多看看书... 总是好的...
[解决办法]
基于类的继承其实是由编译器决定的,编译器可以在编译时计算父类和子类的实例需要多少内存
(仅仅是引用计数、VTable 指针、模块级变量自身的内存,至于字符串、数组、类等变量数据所占的内存是不算在内的),
类实例的大小不是在运行时计算的!
熟读二十四史并不有助与编程,不同的问题还是要看不同的书。
[解决办法]
我只是没兴趣把话说的那么明白... 嗦嗦一大堆...
首先,基本上都可以在编译时确定的,而不是什么大约多少。。。
之后再看书,然后贴上来,更不能说明问题
(看什么书都行,关键是看全、看对,别只看一点)
vtable 记录着一切,就算不能复制一切,也能复制指针,形成带数据引用的继承; 而且叫vtable也不靠谱,并非所有编译器都叫他vtable,所以临时看一点,实在过分
每个编译器对对象的处理方式都不同,对象的定义本身是广泛的为方便编程的,不同的定义的编译器所构建的不同对象编译方式都可以写本书来描述
某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语;
24史没看过,1史都没看过,3国比较喜欢,3字经也研究过,不过我倒是觉得语文老师说多看书是最正确的,也许红楼梦中就写着只顾着泡妞而不讲究方法,也是不行的
正是因为类的继承不是在运行时确定所需的内存大小,而是在编译时就确定了,这个确定过程是基于字符编译的宏来完成的
举个例子,open 语句将一个结构写入文件时,如果结构包含数组,则可以将结构内容全部写入,而不是把结构中的数组的地址写下去,这个例子可能不够恰当,因为这是COM对象特性,对于晚期实现的动态内容,COM对象在编译前和编译后对有效数据都是区别对待的,但例子也可以说明,编译器也好,对象也好,是“智能的(具体内容不在阐述)”,而非将一个4字节数据简单的看成一个long值而已,由此来说明数组之类的东西在复制时的方式
24史中如果包括怎样消灭银河系,那不妨多看;就算是金瓶梅也有很多可取之处。。。
说一点我对看书的经验吧,我看书不象别人,喜欢把书中的内容倒背如流或是练就一手copy大法的到处张贴,我比较喜欢理解着看,印证着看,因为更多时候我是带着问题去看
读的多了,理解深了,可能是摸到了一些本质,对问题的看法也就不同了,随意的就把正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。因为他说的,我理解,而且知道他在开玩笑
[解决办法]
你看书如何如何。。。并不能说明别人就不是如何如何。。。这是最基本的逻辑。。。现代计算机也是基于逻辑的哦
随意的就把正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。……怎么就是正确的内容,爱因斯坦的最大贡献不是原子弹,而是告诉人们没有绝对的正确,只有局部的正确
某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语;。。。怎么看这句话都带有强烈的中国特色
能扯是好的,但无助于问题的解决!
[解决办法]
能扯确实是好的,连基本概念都不懂,就不要扯了
[解决办法]
不要把 VB 和 VC 看得有多么的不同。
到 Visual Studio 6 的目录下搜一下,可以看到两者用了同样的 LINK.EXE。
语言其实就是描述方式不同,底层没什么区别。
对于 COM 对象
VB 基于实现的继承其实就是限定不同的类之间 VTable 完全独立。
VC 基于类的继承其实就是可以在父子类之间复制或直接调用 VTable 内的函数指针。
一切由编译器决定,而无论 VB 还是 VC 开发的 COM 对象,在外部表现和底层结构上没有特殊的区别。
[解决办法]
继承为什么要复制基类呀,那不非要去确定基类需要多少内存?基类的基类需要多少内存?基类里要是用了动态申请内存的,还不疯了?
一个对象在内存里面,数据是属于每个对象自己的,数据里面肯定有个指针指向基类,而不是复制个基类到这个对象来.
对象的方法是公用的,就是程序代码在整个内存中只存在一份,这个类型的所有对象都共享这些程序代码.vb里面都有this,me这样的参数在程序中来区别不同对象.
[解决办法]
好吧,弄了一堆也都没了,你赢了。。。 哪跟哪啊
[解决办法]
看晕了。是教授们自己掐起来了?
[解决办法]
政府为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。
显而易见,政府不可能做到为每个家庭的成员分配相邻房间
现在政府想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样政府只需找这家家长要数据即可;
2、政府自已统计;
想用第2种方案,那就必须清楚每个成员间的关系,这两点如何做到呢?
如果再允许成员可以把房间自由处置,可以拆掉(销毁)、升二层(动态申请)、交换(交换指针)、馈赠和继承……
面对这些,有谁还想自己去统计呢?
所以方案2只是理论可行,实际上有谁会这样做呢?
[解决办法]
[解决办法]
1、类是类,对象是对象,两者不可以混淆的,类相当于块模板,因此可认为不占据运行内存,对象才真正占据内存,好比说“美国人”占领伊拉克,“美国人”这个类去了吗?事实是一些叫做John、Jack的,有“美国人”这个特征的人(对象)占的。
...会说:这是我的3个孩子得地址,你去统计他们吧...
不错,和第一种一样,即都得基于对象的“自觉性”,得靠对象本身
[解决办法]
说到底还是一个指针
[解决办法]
哈,真够热闹的,不过后面好象跑偏了点
我觉得要计算出一个对象所占的精确内存应该是有办法的,只是没什么很大的意义而已.
毕竟所有的内存申请释放都是VB完成的,它自己要是搞不清楚那还怎么搞...
上面有个例子,就是向文件写入自定义类型的变量,OPEN与PUT及GET都能智能地将不包含对象引用的自定义类型进行文件IO,这点在做配置文件时比较方便.
不过不能保存实例化的对象数据,也不能进行对象继承,我估计更多还是基于定位的考虑吧,非不能也,乃不为也.....
扔砖完毕,继续看玉....
[解决办法]
没玉,我是来砌砖的!
[解决办法]
仅供参考
MSDN98中的例子walker又名pwalk。完整列出指定进程的内存使用情况,显示进程地址空间内容,装载哪些DLL,代码、数据、堆栈段分配在何处,可以用来检测内存泄漏,监测内存使用。
http://download.csdn.net/detail/zhao4zhong1/3667896
[解决办法]
钓鱼岛这么紧张,你们还有心思在这儿争论?
[解决办法]
[解决办法]
话题可能越扯越远了,但真心觉得这问题和编绎器扯不上关系!
操作系统关心窗口,进程,线程等等对象,因此从操作系统的角度说,窗口,进程等对象所占内存是可精确计算的,因为操作系统了解它们的结构;但要知道一个用户自定义对象所占内存,操作系统恐怕就无能为力了,因为这些对象并不是直接向操作系统申请,而是由进程等对象代申请,操作系统的帐本上记的是进程的名字,而不是用户自定义对象的名字--当然,如果操作系统愿意为每一个申请内存的对象建帐本就另说!
延伸一点说,进程是否又愿意为进程内的每一个对象建个帐本呢?
从数学的角度说,如果你要了解更详细的收支情况,那你就得有更详细的明细记录表.
为什么要和继承扯上关系统呢?继承是针对类来说的,而不是对象。我们说某类继承自某类,而不是说某对象继承自某对象。
关于复制副本,那要看你怎样理解“副本”这个东西了,B与A的指针成员都指向同一个地方,我们可认为B是A的副本,但从另一个角度说,B与A的指针成员虽然没指向同一个地方,但它们指向的地方的数据都是完全相同的,难道不认为B也是A的副本吗?就像a=1,b=a,虽然a,b地址不一样,但a,b的数据却是一样的。
copymemory只能得到第一种副本,并且算不上真正的副本,修改一下A的指针成员指向的数据,再看看B就知道了。在同一进程内还好,如果copymemory跨进程、跨机器的对象,恐怕可能出现的就是“该内存为XXX”了
关于a=b复制对象,如果知道“重载运算符”就容易多了,可惜,VB6这东西没有“重载”。。。
扯远了,钓鱼岛都这么紧张了,还。。。楼主咋不结贴?虽有不同看法,不过对你的问题意见还是一致的。
[解决办法]
看过代码吗,看懂了吗