php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80951 WeakReferences are collected on scope
Submitted: 2021-04-12 16:11 UTC Modified: 2021-04-12 16:34 UTC
From: alex dot a dot pott at gmail dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 8.0.3 OS: OS X / Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: alex dot a dot pott at gmail dot com
New email:
PHP Version: OS:

 

 [2021-04-12 16:11 UTC] alex dot a dot pott at gmail dot com
Description:
------------
In the WeakReference documentation it says: "Weak references allow the programmer to retain a reference to an object which does not prevent the object from being destroyed. They are useful for implementing cache like structures."

And in the RFC it says:"The application might want to fetch the same serial number multiple times. Fetching the same product again and making a new object could have several problems. It might be slow and expensive."

However the current implementation means thats weak references don't prevent destruction when an object loses scope. This means that a cache service that persists objects in memory can't use the WeakReference object as hoped.

Ideally WeakReferences would prevent an object being destroyed until garbage collection is run.

For more information see https://www.drupal.org/project/drupal/issues/3190992#comment-14055154

Test script:
---------------
$obj = new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref->get());
unset($obj);
var_dump($weakref->get());
gc_collect_cycles();
var_dump($weakref->get());

Expected result:
----------------
object(stdClass)#1 (0) {
}
object(stdClass)#1 (0) {
}
NULL

Actual result:
--------------
object(stdClass)#1 (0) {
}
NULL
NULL

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-04-12 16:34 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2021-04-12 16:34 UTC] nikic@php.net
WeakReferences have no impact on the object lifecycle at all -- that's their whole point. The object will be destroyed at exactly the same time it would be destroyed if it had no weak references.

I couldn't find the wording you quoted in the accepted RFC (https://wiki.php.net/rfc/weakrefs). Apparently it was part of an older RFC (https://wiki.php.net/rfc/weakreferences).

Note that the canonical use-case for weak references is in the form of WeakMap, where a cache value is associated with a weak object identifier, not the other way around.
 [2021-04-13 10:05 UTC] alex dot a dot pott at gmail dot com
Thanks for the reply nikic.

I've looked at PHP's implementation of WeakMap as well. And it seems to empty when an object loses scope - at least according to https://php.watch/versions/8.0/weakmap.

With an application like Drupal where a memory cache is used to prevent reloading objects from a database, if they are used in multiple parts of building a response for a page then, an object will lose scope once that part of a page is built. Therefore if we converted our memory cache to use a weakmap we'd end up having to reload an object even though we've not run out of memory. Looking at implementation examples in the Java world they all require the equivalent of gc_collect_cycles() to run. See https://www.baeldung.com/java-weakhashmap#weakhashmap-as-an-efficient-memory-cache for example.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Tue May 17 08:05:45 2022 UTC