如何获取对象变量所占字节数?【100分】

高手都到碗里来 2012-08-24 11:27:15
我们定义了一个对象变量
比如
dim obj as object
然后
set obj=creatobject("test.test")

然后做一些操作,插入数据,赋值之类的

接下来,如何获取这个obj到底占用了多少字节的内存呢?
...全文
809 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
PctGL 2012-09-16
  • 打赏
  • 举报
回复
看过代码吗,看懂了吗
  • 打赏
  • 举报
回复
好吧,结扎!
c_cyd2008 2012-09-15
  • 打赏
  • 举报
回复
话题可能越扯越远了,但真心觉得这问题和编绎器扯不上关系!

操作系统关心窗口,进程,线程等等对象,因此从操作系统的角度说,窗口,进程等对象所占内存是可精确计算的,因为操作系统了解它们的结构;但要知道一个用户自定义对象所占内存,操作系统恐怕就无能为力了,因为这些对象并不是直接向操作系统申请,而是由进程等对象代申请,操作系统的帐本上记的是进程的名字,而不是用户自定义对象的名字--当然,如果操作系统愿意为每一个申请内存的对象建帐本就另说!

延伸一点说,进程是否又愿意为进程内的每一个对象建个帐本呢?

从数学的角度说,如果你要了解更详细的收支情况,那你就得有更详细的明细记录表.

为什么要和继承扯上关系统呢?继承是针对类来说的,而不是对象。我们说某类继承自某类,而不是说某对象继承自某对象。

关于复制副本,那要看你怎样理解“副本”这个东西了,B与A的指针成员都指向同一个地方,我们可认为B是A的副本,但从另一个角度说,B与A的指针成员虽然没指向同一个地方,但它们指向的地方的数据都是完全相同的,难道不认为B也是A的副本吗?就像a=1,b=a,虽然a,b地址不一样,但a,b的数据却是一样的。

copymemory只能得到第一种副本,并且算不上真正的副本,修改一下A的指针成员指向的数据,再看看B就知道了。在同一进程内还好,如果copymemory跨进程、跨机器的对象,恐怕可能出现的就是“该内存为XXX”了

关于a=b复制对象,如果知道“重载运算符”就容易多了,可惜,VB6这东西没有“重载”。。。

扯远了,钓鱼岛都这么紧张了,还。。。楼主咋不结贴?虽有不同看法,不过对你的问题意见还是一致的。
赵4老师 2012-09-12
  • 打赏
  • 举报
回复
仅供参考
MSDN98中的例子walker又名pwalk。完整列出指定进程的内存使用情况,显示进程地址空间内容,装载哪些DLL,代码、数据、堆栈段分配在何处,可以用来检测内存泄漏,监测内存使用。
http://download.csdn.net/detail/zhao4zhong1/3667896
东方之珠 2012-09-12
  • 打赏
  • 举报
回复
没玉,我是来砌砖的!
PctGL 2012-09-12
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 的回复:]
[/Quote]

乐色马

open,put,get 所指的意义是,对于vb预定义的大多数变量类型的存取,不是简单的字节读写
不是简单的内存copy,由此说明vb类副本的可行性
vb的不行完全在于编译器根本不处理这些,vb和vc的编译器有着非常大的区别
link.exe 一样编译方法,方式,内容就一样? 各位看官知不知道 link.exe 仅仅是连接器,他把编译器编译好了的模块文件组合成一个 exe而已? 只是vc .net 版本后新增了link时代码的优化

我再明确下,我的观点:
可以,但并非完全可以;之前已经说过,编译器不支持,自己折腾来折腾去的总也好不到哪去,因为这需要从根上解决

再举个例子:
vb Class1's vtable:

memory | sub names & type
+0 function:iunknow
+4 function:addref
+. function:...
+24 function:------ 前 28字节重型接口略
+32 function:mysub1
+36 function:myproperty1
+40 function:myproperty1
+44 function:myPublicVar1
+48 function:myxxx
+.. function:------ N 个 * 4 字节公用: 属性,方法,变量略
+.. +4 function:mysub1
+.. +8 function:myproperty1
+.. +12 function:myproperty1
+.. +16 function:myfPrivateVar1
+.. +20 function:myxxx
+.. +. function:------ N 个 * 4 字节私有: 属性,方法,变量略

以上为某 class 类型vb对象在内存中的详细map
帖子内容,全部是自己手动写上来的, 如果哪弄错了, 凑合看吧... 应该不难理解
这就是一个完整的 vtable map
形式上看就是个 结构类型
公共部分不说了,一般来讲如果要复制副本,直接copy即可,因为大部分方法也好,变量也好,都是以地址方式保存的,因为要支持晚期调用
妨碍我们进行复制的就是私有的部分,私有部分内容只有编译器在编译时清楚到底放进去了多少内容,这和你声明的类局部变量数量,私有函数,方法,过程,属性有关

在表的私有内容部分,如果有 as long 类型, 直接复制即可, 你说你存的是一个新申请的内存指针,但如果需要进行副本复制,这里只复制 long 数据,其余不理,道理大家该理解。诸如此类,预定义类型,如 integer,byte,single,double等通通如此

特别一些的是 string,class,array (还有更多);这些内容的复制并非无法实现,最简单的是 a =b 即复制了一个新的,但私有部分的内容是隐蔽的,编译器从根本上不提供这项功能
如果还是需要复制副本的功能,就可以用copymemory的方法实现了,知道了这个表长度直接复制即可

我做了一个最简单的: 复制对象
演示代码: http://files.cnblogs.com/pctgl/copy2new.rar

内有详细注释, 很简单

提示: 以上代码仅做演示一途, 绝非万全之策, 切不可用于正式项目,但也算较为安全,不会轻易弄挂你的程序


以后就是这帖的看客了, 各位有想多研究这方面的,不如来我的blog一起研究 pctgl.cnblogs.com
贝隆 2012-09-12
  • 打赏
  • 举报
回复
钓鱼岛这么紧张,你们还有心思在这儿争论?
嗷嗷叫的老马 2012-09-12
  • 打赏
  • 举报
回复
哈,真够热闹的,不过后面好象跑偏了点

我觉得要计算出一个对象所占的精确内存应该是有办法的,只是没什么很大的意义而已.

毕竟所有的内存申请释放都是VB完成的,它自己要是搞不清楚那还怎么搞...

上面有个例子,就是向文件写入自定义类型的变量,OPEN与PUT及GET都能智能地将不包含对象引用的自定义类型进行文件IO,这点在做配置文件时比较方便.

不过不能保存实例化的对象数据,也不能进行对象继承,我估计更多还是基于定位的考虑吧,非不能也,乃不为也.....

扔砖完毕,继续看玉....
  • 打赏
  • 举报
回复
boywang 2012-09-05
  • 打赏
  • 举报
回复
说到底还是一个指针
王二.麻子 2012-08-31
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

政府为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。

显而易见,政府不可能做到为每个家庭的成员分配相邻房间

现在政府想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样政府只需找这家家长要数据即可;
2、政府自已统计;……
[/Quote]
派生类能知道基类的内存数?或者基类知道派生类的内存数?
例子挺好,却不完美.

那当爹的遇到政府分房子,会说:这是我的3个孩子得地址,你去统计他们吧...
c_cyd2008 2012-08-31
  • 打赏
  • 举报
回复
1、类是类,对象是对象,两者不可以混淆的,类相当于块模板,因此可认为不占据运行内存,对象才真正占据内存,好比说“美国人”占领伊拉克,“美国人”这个类去了吗?事实是一些叫做John、Jack的,有“美国人”这个特征的人(对象)占的。


...会说:这是我的3个孩子得地址,你去统计他们吧...

不错,和第一种一样,即都得基于对象的“自觉性”,得靠对象本身
of123 2012-08-29
  • 打赏
  • 举报
回复

看晕了。是教授们自己掐起来了?
PctGL 2012-08-29
  • 打赏
  • 举报
回复
好吧,弄了一堆也都没了,你赢了。。。 哪跟哪啊
王二.麻子 2012-08-29
  • 打赏
  • 举报
回复
继承为什么要复制基类呀,那不非要去确定基类需要多少内存?基类的基类需要多少内存?基类里要是用了动态申请内存的,还不疯了?

一个对象在内存里面,数据是属于每个对象自己的,数据里面肯定有个指针指向基类,而不是复制个基类到这个对象来.
对象的方法是公用的,就是程序代码在整个内存中只存在一份,这个类型的所有对象都共享这些程序代码.vb里面都有this,me这样的参数在程序中来区别不同对象.
Tiger_Zhao 2012-08-29
  • 打赏
  • 举报
回复
不要把 VB 和 VC 看得有多么的不同。
到 Visual Studio 6 的目录下搜一下,可以看到两者用了同样的 LINK.EXE。

语言其实就是描述方式不同,底层没什么区别。
对于 COM 对象
VB 基于实现的继承其实就是限定不同的类之间 VTable 完全独立。
VC 基于类的继承其实就是可以在父子类之间复制或直接调用 VTable 内的函数指针。
一切由编译器决定,而无论 VB 还是 VC 开发的 COM 对象,在外部表现和底层结构上没有特殊的区别。
c_cyd2008 2012-08-29
  • 打赏
  • 举报
回复
政府为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。

显而易见,政府不可能做到为每个家庭的成员分配相邻房间

现在政府想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样政府只需找这家家长要数据即可;
2、政府自已统计;

想用第2种方案,那就必须清楚每个成员间的关系,这两点如何做到呢?
如果再允许成员可以把房间自由处置,可以拆掉(销毁)、升二层(动态申请)、交换(交换指针)、馈赠和继承……
面对这些,有谁还想自己去统计呢?

所以方案2只是理论可行,实际上有谁会这样做呢?

PctGL 2012-08-28
  • 打赏
  • 举报
回复


我只是没兴趣把话说的那么明白... 啰啰嗦嗦一大堆...

首先,基本上都可以在编译时确定的,而不是什么大约多少。。。
之后再看书,然后贴上来,更不能说明问题
看什么书都行,关键是看全、看对,别只看一点

vtable 记录着一切,就算不能复制一切,也能复制指针,形成带数据引用的继承; 而且叫vtable也不靠谱,并非所有编译器都叫他vtable,所以临时看一点,实在过分

每个编译器对对象的处理方式都不同,对象的定义本身是广泛的为方便编程的,不同的定义的编译器所构建的不同对象编译方式都可以写本书来描述

某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语;
24史没看过,1史都没看过,3国比较喜欢,3字经也研究过,不过我倒是觉得语文老师说多看书是最正确的,也许红楼梦中就写着只顾着泡妞而不讲究方法,也是不行的

正是因为类的继承不是在运行时确定所需的内存大小,而是在编译时就确定了,这个确定过程是基于字符编译的宏来完成的

举个例子,open 语句将一个结构写入文件时,如果结构包含数组,则可以将结构内容全部写入,而不是把结构中的数组的地址写下去,这个例子可能不够恰当,因为这是COM对象特性,对于晚期实现的动态内容,COM对象在编译前和编译后对有效数据都是区别对待的,但例子也可以说明,编译器也好,对象也好,是“智能的(具体内容不在阐述)”,而非将一个4字节数据简单的看成一个long值而已,由此来说明数组之类的东西在复制时的方式

24史中如果包括怎样消灭银河系,那不妨多看;就算是金瓶梅也有很多可取之处。。。

说一点我对看书的经验吧,我看书不象别人,喜欢把书中的内容倒背如流或是练就一手copy大法的到处张贴,我比较喜欢理解着看,印证着看,因为更多时候我是带着问题去看
读的多了,理解深了,可能是摸到了一些本质,对问题的看法也就不同了,随意的就把正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。因为他说的,我理解,而且知道他在开玩笑

Tiger_Zhao 2012-08-28
  • 打赏
  • 举报
回复
基于类的继承其实是由编译器决定的,编译器可以在编译时计算父类和子类的实例需要多少内存
(仅仅是引用计数、VTable 指针、模块级变量自身的内存,至于字符串、数组、类等变量数据所占的内存是不算在内的),
类实例的大小不是在运行时计算的!

熟读二十四史并不有助与编程,不同的问题还是要看不同的书。
PctGL 2012-08-28
  • 打赏
  • 举报
回复
...............

书中自有颜如玉... 书中自有黄金屋... 多看看书... 总是好的...
加载更多回复(18)

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧