4

In Swift, great emphasis has been placed on strong reference cycle, and different ways to avoid it. If there are strong reference cycle between two variables, they will keep each other in memory forever, and cause the program to crash if large images or videos are been kept in memory by strong reference cycle.

I was just wondering if such concept exist in Java? Is it possible to unintentionally create something similar to strong reference cycle in Java? I have several months of Java experience, but I have never heard of anyone mentioning such concept in Java, even though Java do use reference variables to point to objects.

halfer
  • 19,824
  • 17
  • 99
  • 186
Thor
  • 9,638
  • 15
  • 62
  • 137

1 Answers1

9

It seems that swift uses "reference counting" to detect object liveness: each object has a counter associated with it that gets incremented if a new reference to that object is created and gets decremented if a reference to that object disappears. An object is dead if the reference count is zero, meaning that there are no more references to it.

Java on the the other hand uses "reachability" as a measure of liveness: an object is alive as long as there exists a reference chain from some "running code" to the object.

There are pros and cons to both approaches:

  • reference counting makes the garbage collectors life easier: just look at the reference count and you know whether an object is alive
  • on the other hand, reference counting makes it possible to create reference cycles between otherwise dead objects
  • reachability means that the garbage collector has to start at the objects that a thread can directly reach and follow all references to mark live objects
  • reachability on the other hand means that reference cycles are no problem: either both objects are reachable or neither one
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • so basically garbage collection happens in runtime in Java but during compile time in Swift? – Ali Mir Sep 12 '17 at 23:36
  • 1
    @AliMir The Swift compiler just adds some code to support the garbage collector - the garbage collection process itself always happens at runtime. A method that allocates an object could be called never, once or millions of times - the compiler doesn't know it and doesn't care. – Thomas Kläger Sep 13 '17 at 04:25
  • Reference counting requires otherwise unnecessary memory fences in multithreaded environment, which may lead to performance degradation. https://stackoverflow.com/questions/2599238/are-memory-barriers-necessary-for-atomic-reference-counting-shared-immutable-dat – Basilevs Apr 11 '18 at 12:19
  • 2
    @Basilevs that's not the only issue. The reference counting gc *must* take action when the counter reaches zero, i.e. free the object's memory which boils down to remembering that this (likely rather small) chunk of memory is free, even when the memory might be never needed again. Then, these chunks must be merged at some point (when possible), to get a larger contiguous free memory block. A copying/compacting gc only runs when memory is truly needed and intrinsically produces a large contiguous free memory block. With sufficient spare memory, this is way more efficient. – Holger Sep 10 '20 at 07:28