Posts

Don't mix objects and interfaces

Image
Mixing objects and interfaces in classic (non-ARC) Delphi is a huge no-no. That part is clear. What that actually means is more of a blur. After all there is a object instance lying behind every interface reference. So what is wrong with mixing objects and interfaces? object references are weak, interface references are strong reference counted object instances need at least one strong reference to keep them alive therefore you can't use object reference as primary owning reference reference counted object instances can be safely accessed through temporary, short-lived (weak) object references, as long as there are strong reference(s) keeping the object alive The real issue behind the mixing of objects and interfaces is not the mixing itself, but the lack of initial strong (interface) reference to object instance, or accessing the reference counted object instance through weak (object) reference after the last strong (interface) reference has gone out of scope and t...

Optimizing ARC - weakness of [weak]

In Delphi, the [weak] attribute is used to break strong reference cycles between reference counted object instances. It can be used with the ARC compiler on both object and interface references, and with the classic compiler for interface references. Weak interface references were introduced in Delphi 10.1 Berlin. Now, there is a teeny-weeny problem with the [weak] attribute. It denotes a zeroing weak reference that will be zeroed (niled) when the object it points to is no longer valid. In order to do that, the compiler has to track such objects at runtime and that introduces some overhead. If you are tracking many such references, that can introduce a significant performance loss. Not all weak references that serve the purpose of breaking reference cycles need to be zeroed out. If you can guarantee that a [weak] reference will never outlive the object it points to, all that tracking and zeroing is useless. To avoid a performance penalty in such cases, you can use the [unsafe] ...

Exceptional Safety

Delphi is exception safe language. That means well written code can recover from the most horrible exceptions, including the dreaded out of memory error, and continue running in a perfectly operational state - as if nothing bad happened. Of course, that is a feature that Delphi provides, but your code and application eventually must determine logic at which point raised exception is recoverable and at which point it is not. For instance, if you allow user to open some external file for further processing and your code trips on out of memory exception because the file is too large to process, you can fully recover from such event, show error message to the user "Sorry, selected file is too big" and application can merrily continue working. On the other hand if you trigger out of memory error during some operation your application absolutely must be able to perform, you can decide that the best course of action is terminating the application - after you show appropriate error...

Optimizing ARC the hard way

One of the potentially unnecessary ARC triggers is passing a reference counted entity as a parameter. Depending on the parameter's declaration, the compiler might insert transient reference counting code in the prologue and epilogue of the called procedure (function, method). Parameters passed with the default (value) semantics will trigger the reference counting mechanism. On the other hand, parameters passed as references - declared as var , const , [ref] , [weak] or [unsafe] - will not trigger the reference counting mechanism while entering and exiting the procedure. There is nothing new here. Delphi COW copy-on-write strings are reference counted, and passing strings as const parameters is a commonly used optimization pattern. The same principle applies not only to strings, but also to all other reference counted entities, like dynamic arrays, variants, interface references, anonymous method references, and additionally object references on Delphi ARC compilers. Why t...

Optimizing ARC with unsafe references

Image
ARC recognizes two types of references: strong and weak . Strong references are ones that participate in the reference counting mechanism, and weak references are references that do not participate in reference counting. While there is more than one way of achieving weak references, the ones that conceptually fit into ARC memory management are zeroing weak references. Zeroing weak references are niled (set to zero) when the object instance they point to is destroyed. A combination of strong and zeroing weak references leaves no room for invalid pointers. At all times, you will be dealing with references that are either nil or point to a valid object instance. Sounds perfect, doesn't it? Well, at least in theory. In practice, just like reference counting itself adds some small amount of overhead, zeroing weak references add some more. In order to zero out weak references after the object instance they point to is destroyed, the application has to track them at runtime and tha...

Delphi Memory Management for Classic and ARC Compilers - eBook Update

Image
Due to the popular demand (I believe two or three guys asked for it), we eventually added the Mobi format to the existing PDF and ePub options for the eBook. It's added to the download links for the new orders, but I decided not to send you all the file via email this time. If anyone is interested, just send me a note and I'll reply with the download link. Make sure you're writing from the same email address you used while ordering the book in the first place! This is intended only for the existing registered owners of the eBook! If you're looking for the ordering page, here it is: Order Delphi Memory Management For Classic And ARC Compilers eBook

What is thread safety anyway?

Multithreading can be hard to do right. The most common point of failure is assuming some code is thread safe when it actually is not. And then the whole multithreading castle crumbles into ruins. "Thread safe" is a pretty vague term. If you are not sure what it actually means, I suggest you start by reading Eric Lippert's blog post on the subject. On the other hand, if you do know what thread safety is, well, I suggest you read it anyway  🙂 What is this thing you call "thread safe"? Wrong assumptions When it comes to thread safety in Delphi (actually, this is not a Delphi-specific thing) there is very little built in by default. Basically, if you are writing some code that has to be thread safe, you have to take care of the thread safety part all by yourself. And you have to be very careful with your assumptions, as you can easily come to the wrong conclusions. To demonstrate how deeply unsafety goes, and how easy is to make wrong assumptions, I ...