Question

I have some code that uses WeakReference. I had to implement an ugly workaround to solve the problem, but I wonder if just adding a this.synchronized might solve my problem with the garbage collector. Here is the code, the problem is in the function create

  /**
   * The canonical map.
   */
  var unicityTable = new WeakHashMap[CanonicalType, LightWeightWrapper[CanonicalType]] with SynchronizedMap[CanonicalType, LightWeightWrapper[CanonicalType]]

  /**
   * Create a new element from any object.
   * @param from the object that will be used to generate a new instance of your canonical object.
   */
  def create(from: FromType) = {
    val newElt = makeFrom(from)
      // I wonder if adding a this.synchronized here (and of course removing the test for garbage collection) might solve the problem more elegantly 
      val wrapper = unicityTable.get(newElt)
      wrapper match {
        case Some(w) => w._wrap.get match { // if the element is in the map
          case Some(element) => element // the element was not garbage collected while we obtaining it
          case None => // some how, the wrapped element was garbage collected before we get it, so we recreate it, and put it back
            unicityTable.put(newElt, LightWeightWrapper(newElt))
            newElt
        }
        case None => // the element is not in the map
          unicityTable.put(newElt, LightWeightWrapper(newElt))
          newElt
      }

  }

  class LightWeightWrapper[T <: AnyRef] private (wrap: T) {

    val _wrap = new WeakReference(wrap)

    def wrapped = _wrap.get match {
      case Some(w) => w
      case None => // should never happen 
        throw new IllegalStateException
    }

    override lazy val hashCode = wrapped.hashCode

    override def equals(o: Any): Boolean = o match {
      case LightWeightWrapper(w) => w eq this.wrapped
      case _ => false
    }
  }

So the question is: Does garbage collection stop during the execution of a synchronized block?

Was it helpful?

Solution

No, garbage collection still happens inside of synchronized. Also, this will already be prevent from being garbage collected because it is on the stack, so you aren't getting any help there either.

I'm not sure what you are doing, but I think maybe you really want to be using SoftReference rather than WeakReference. Objects that are only referenced by a WeakReference may be collected as soon as all hard references are gone. Objects referenced only by a SoftReference may be kept until the VM runs low on memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top