#46
|
|||
|
|||
O_o, quite interesting
May I ask you a few questions about your new function of the last upload? 1. Code:
Public Const coBytes As Long = 4 * 8 2. Quote:
3. Curiousity - I've never seen this before: Code:
wordCount = Length \ wordLength |
#47
|
||||
|
||||
Slow "comparison/replace" script
Quote:
The Mem_Read for VarPtr is still set to 4 (it should be set to POINTER_LENGTH in fact). Quote:
The main point is that we can confirm the relationship between VarPtr and ObjPtr for objects. We can confirm that the Loal Object, is just a LongPtr containing the address of the referenced object or zero, depending on if its been set or not. Before I unscrambled the bytes, it was not obvious that the Mem_Read from VarPtr was in fact the address of the global object. But now we are clear on that. So, using your Mod01 as an example, it means that we can say with 100% confidence that, after runtime: If Mem_ReadHex_Words(lng_objPtr, 4) = 0 then objwks is set to Nothing If Mem_ReadHex_Words(lng_objPtr, 4) = ObjPtr(Sheet1) then objwks has not been properly released If Mem_ReadHex_Words(lng_objPtr, 4) <> ObjPtr(Sheet1) then objwks has been properly released Thus solving the problem that you raised earlier about ObjPtr returning the same thing for the local and global variables. Quote:
Run this code... Code:
Sub testIntDiv() Debug.Print 3 / 5 Debug.Print 3 \ 5 End Sub if p / q = p\ q then p is divisible by q Last edited by CoolBlue; 06-24-2014 at 07:30 PM. |
#48
|
|||
|
|||
Thanks, for the explanations
I agree and I'm delighted that your function Mem_ReadHex_Words shows the relation to HexPtr(ObjPtr) clearly now. On the proof for the release of memory I also agree, though it's more complicated as you showed: Quote:
If Mem_ReadHex_Words(lng_varPtr, 4) doesn't point anymore to HexPtr(lng_objPtr, 4) And Mem_ReadHex_Words(lng_objPtr, 4) <> Mem_ReadHex_Words(ObjPtr(Sheet1)) should proof that memory has been released. (But that's just for the record, I think you meant the same) Quote:
Therefore, all we have to do: Thinking up a routine where reference count fails |
#49
|
||||
|
||||
Slow "comparison/replace" script
Quote:
Quote:
Actually I thought it was me who changed your code and left the 4 there Im building a class module now to encapsulate this stuff to make it more convenient to deploy. I have some problem related to the need to pass the variable/object into the class as a variant type, i need to make sure the original address is available inside the class, so I just need solve that. I guess its got something to do with decoding the Variant Type structure but the Bytecomb site is very helpful on that, so shouldn't be a problem i think... |
#50
|
|||
|
|||
I see your correction, but you still left out an important thing:
Quote:
I have to come back on the example in my file for Run11_clsTest(). It actually doesn't show that the class got destroyed. I made an attempt to obtain the VarPtr and ObjPtr for Class1, but it didn't work therefore I left it. Now I figured it out: Class1: Code:
Public Sub Class_Initialize() Debug.Print "Class1 is initialized" lng_objcls1 = ObjPtr(Me) lng_varcls1 = VarPtr(Me) pointerToSomething "objClass1", lng_varcls1, lng_objcls1, coBytes End Sub Code:
lng_objcls1 = ObjPtr(Class1) Checking on these datas afterwards, it shows properly that the class gets terminated: Mod11_Class: Code:
Sub Run11_clsTest() Do_Header "Running Test_Class..." Test_Class DoEvents Debug.Print "After Runtime" pointerToSomething "objcls1", lng_varPtr, lng_objPtr, coBytes pointerToSomething "objClass1", lng_varcls1, lng_objcls1, coBytes End Sub Quote:
|
#51
|
||||
|
||||
Quote:
Quote:
ObjPtr(Class1) is like VarPtr(LongPtr) or ObjPtr(Collection) These are semantic representations of definitions of data structures, not objects. But, yep, that is what the Me statement is for. It refers to the particular instance of the object of type Class1. So every instance of type Class1 has its own "Me"... a pointer to itself. But a Class cannot have a pointer to itself, coz it's not an object, only a definition of a type of object. I'n not sure what VarPtr(Me) is though... I can't figure that on out and the contents of that location are zero. That one is making my head spin Quote:
I am hoping to have something like this... Code:
Sub testObj() Const objBytes As Long = 32 Dim o As clReferrence Dim lObj As Worksheet Set gwks = Worksheets(1) Set lObj = gwks Set o = New clReferrence o.initObject objBytes, lObj Debug.Print "Address: " & o.Address & vbTab & "Contents: " & o.Contents Debug.Print "pAddress: " & o.pAddress & vbTab & "pContents: " & o.pContents End Sub |
#52
|
|||
|
|||
Quote:
Quote:
Code:
Private Sub Test_Class() Dim objcls1 As Class1 Set objcls1 = New Class1 lng_objPtr = ObjPtr(objcls1) lng_varPtr = VarPtr(objcls1) pointerToSomething "objcls1", lng_varPtr, lng_objPtr, coBytes 'Since VarPtr(Me) obtained in the class shows Zero check again: pointerToSomething "objClass1", lng_varcls1, lng_objcls1, coBytes Set objcls1 = Nothing If objcls1 Is Nothing Then Debug.Print vbTab & "Object is set to nothing" Else Debug.Print vbTab & "Object wasn't cleared before leaving Sub" End If pointerToSomething "objcls1", lng_varPtr, ObjPtr(objcls1), coBytes End Sub Code:
Set objcls = New Class1 With ObjPtr(Me) established objcls next is assigned a pointer VarPtr which points to the instance of Class1, and at this stage also VarPtr(Me) gets the reference. Pretty sure it's just a inside thing why it is like that. One explanation might be, that this way, in case the Set of objcls fails it's easier to release memory (but that's just a home-made explanation). But as you already said some time ago, this part isn't that important. In the moment I'm doing some examples with various objects. When it comes to charts, that's rather confusing. It's somehow weird, which pointer (VarPtr) suddenly points to another object, though I expect it pointing to yet another object. But that's only a thing of memory management, and we don't have to dive deeper, as long at the end the references show that they got removed. As for the other part: I leave you struggling, assuming if you don't get it working I won't either. The snippet of the code anyway leaves too much to guess. |
#53
|
||||
|
||||
errmm... back to this thoroughly hijacked thread...
I was doing some other stuff for a while, but I haven't forgotten about this... I made a tool to parse the memory structure of these objects and I can show a map of what is going on in your Mod02_objRange module... When you measure these structures, you need to make sure you take a snap shot of everything at the same time, otherwise they will get out of phase as the stack moves around. For example, if you read VarPtr in your Test_rng routine and then do the MemRead in PointerToSomething, it will be wrong because the location of the variable has popped further up the stack after the call. But, if you take a snap shot of everything, then, even if they start from different addresses, they will resolve back to the object. The second complication you get when you call a routine to do the measurements, is that new variables are created along the way, extending the chain of pointers back to the object. And if this is not confusing enough, some of the scalar references are wrapped into "Variant References". You can read about these in your Byte Comb site... If you are dealing with objects (Range objects for example) and you see 00000009 or 00004009 at the location pointed to by VarPtr(object), then it is the first frame of a 4 word variant structure and the actual value (if its a pointer) is in the 3rd word of the structure, so you have to add 8 (4 bytes) to your VarPtr(obj) value to find the actual contents. And even more confusing, the 4 flags it as a "By Ref Variant", meaning that the 3rd word points to a pointer to the actual value. You can follow this in the attached snap shot. The top half is the results of my tool, and the bottom half is the readings that you would get from your PointerToSomething. The starting point of the pointer chains is different because they are floating up and down the stack, but, after you unravel these complexities, they always resolve back to the same object. Although its useful for investigating the memory structure, the range object is not a useful example for checking garbage collection since no object structures are created... there are only references to global Range Objects which are not part of VBA's garbage collection. When I get time I'll continue on with this tool to use it on relevant examples. But anyway, you said the Range objects were acting strange so maybe this will clear that up... |
#54
|
|||
|
|||
Hi CoolBlue
Sorry, it took me longer as I told in the PM. Now, that seems to become a fulltime job - I'm not sure if I can summon up that time. I studied your pic now for quite a while and wonder how serious you're about the reference of rawSheets(1).Range("A1") and rawSheet1.Range("A1") Be aware that though basically it's the same object, the references or pointers may differ. Sheets(1) is an object of a spreadsheet relative to its position in the workbook whereas Sheet1 is a - you may say - static object within a workbook. I don't know if it is the right thing to put it, but to explain it more visually: For Sheets(1): Is assigned a pointer, which itself points to the object Sheet1. To say there are 2 pointers necessary. Sheet1 instead, as it is the end of the line of objects, only needs 1 pointer. So don't get confused, if the two cases show different pointers. Quote:
I think the key would be to know about the structure of an object. Unfortunately the CombSite stops before he comes to this. On purpose? I can imagine, that the structure is quite difficult. Probably even containing references to various pointers, which all together only forming an object? Quote:
I rather imagine memory like a town, there are districts (which get assigned to a program as excel), within the district there are streets containing numbers (pointers) which hold the references. An inhabitant (value/object/whatsoever) either lives their (during runtime) or get moved out (by the garbage collector, or by setting it to nothing in case of objects) That would lead us back to us establishing: A pointer (varPtr) contaning any other information as during runtime, allows the conclusion that references got destroyed and memory is freed. |
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Wierd "script code" in a downloaded .doc file | CNBarnes | Word | 2 | 10-18-2012 02:07 AM |
replace data from variable with "sub and super script" from excel to word by vba | krishnaoptif | Word VBA | 9 | 06-22-2012 05:08 AM |
How to choose a "List" for certain "Heading" from "Modify" tool? | Jamal NUMAN | Word | 2 | 07-03-2011 03:11 AM |
Rules and Alerts: "run a script"? | discountvc | Outlook | 0 | 06-15-2010 07:36 AM |
An "error has occurred in the script on this page" | decann | Outlook | 8 | 09-03-2009 08:54 AM |