Heres an interesting one......

Heres an interesting one......

I am upgrading some unit testing from XE2 to XE5.  Most things are working and apart from a couple of hiccups generally with code changes not being tested (my fault, its my code after all) I've not found anything to concern me.

However - I have changed the code being tested from using Containers.TObjectList to Generics.Collections.TObjectList.  Code wise its a minor thing and operationally the component appears to work as before.

BUT there appears to be an odd case of memory addresses being reused now.  I am getting a test failing because I am creating a list of objects, then testing the clear and reset code.  The code clears the objectlist, the contained object destructors are fired and then the component resets to a blank state.  This involves resetting a bunch of stuff to default values and creating and storing a new instance of one of the contained objects.

NOW (keep up here) I am testing for the address of the newly contained object changing, I did this to make sure that the clear down and reset code worked correctly.  I've never really checked to closely, but now its running in XE5 the new object has the same address as the old - in fact its the same as the last of the previously contained objects (there were several).  Debugging the process I can see the constructor getting fired, memory being initialised so I'm not concerned that anything is wrong, but it struck me as odd that the tests never showed this before.  TBH the test itself can complete by checking that the default values are set and memory cleared, so I will go and do that, but I wondered if this is expected?

Comments

  1. If I understand correctly, you have a case where a newly crated object get the address of a previously destroyed object. This is perfectly normal and expected. It has always been so.

    ReplyDelete
  2. I thought as much, I've just never seen it before in practice. It's a corner case tbh, but I what with coping with arc when using Android (testing this kind of thing requires extra thought) I did wonder what was happening. I verified contructors and destructors being run, which was the important thing.

    My concern was that generics.collections was not freeing contained objects, but that's not the case here (I will have to test that on Android though).

    ReplyDelete
  3. Make sure you run with FastMM4 in FullDebugMode. If it doesn't fail, then it is expected behaviour when freeing exactly the same memory in the same order as reusing that memory. Not very common, but it does occur more often than you might think.

    ReplyDelete
  4. That's a good point actually, fastmm is compatible with xe5 these days too, I have a couple of other tests to nail down first and then I will have to try that!

    ReplyDelete
  5. its not a corner case, or your application would very quickly run out of addressable memory. reusing free'd memory is normal.

    ReplyDelete
  6. Yeah, but I have still never seen two objects come back with the address though, memory reuse I expected, I have just never seen a case where the addresses are the same.  As I said its most likely a case of specifically how the test is working, rather than an intrinsic problem - its just I was test to see if the object changed by checking the memory address of the object, which then failed where it hadn't before. Strange that it will now consistently do it, but wouldn't in XE2.  Something has changed with the memory manager.

    ReplyDelete
  7. Paul, if you have to the if an object had changed, don't use his address. Add an integer field to the object which is (interlocked)incremented in the constructor.

    ReplyDelete
  8. François Piette yeeees, but I don't want to add something like that just for the testing, besides its possible that could degrade performance in a multi threaded scenario. If it was required for the actual use of the object, fine, but not otherwise

    ReplyDelete

Post a Comment