php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65663 Excessive memory usage with APC 3.1.13 + PHP 5.4 + Static members + Inheritance
Submitted: 2013-09-12 19:41 UTC Modified: 2013-09-18 15:03 UTC
From: askalski at gmail dot com Assigned:
Status: Suspended Package: APC (PECL)
PHP Version: 5.4.19 OS: RHEL6
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.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: askalski at gmail dot com
New email:
PHP Version: OS:

 

 [2013-09-12 19:41 UTC] askalski at gmail dot com
Description:
------------
I'm running into an issue with APC (unnecessarily?) caching a copy of the current values of inherited static variables when caching opcodes for a derived class.  This causes exceessive memory use, both in the APC cache itself, and by the scripts which are later loaded from cache.  (In the scenario I'm troubleshooting, there is a widely-used base class which keeps up to ~1MB of data in a static array, so the memory usage issue is particularly severe, because that 1MB gets multiplied many times.)

The cause seems to be copying around the entire 'default_static_members_table' of the class.  Would it be possible/safe to exclude copying array slots of inherited static members, and copy only those members which belong to the derived class itself?


Test script:
---------------
<?php /* 1.php */
if (isset($_GET['clear'])) { echo "Clearing opcode cache.\n"; apc_clear_cache('system'); exit; }
class A { public static $var; }
if (isset($_GET['bytes'])) A::$var = str_repeat('x', (int) $_GET['bytes']);
$usage0 = memory_get_usage();
echo "Memory usage before including subclasses: ", ($usage0 = memory_get_usage()), "\n";
require_once("2.php");
$diff = ($usage = memory_get_usage()) - $usage0;
echo "Memory usage after including subclasses: $usage (difference: $diff)\n";
?>

<?php /* 2.php */
class B1 extends A { } class B2 extends A { } class B3 extends A { } class B4 extends A { }
class B5 extends A { } class B6 extends A { } class B7 extends A { } class B8 extends A { }
?>


Expected result:
----------------
The change in memory usage before/after including the derived classes file (2.php) should be small.

$ curl http://$HOSTNAME/1.php?clear
Clearing opcode cache.

$ curl http://$HOSTNAME/1.php?bytes=5444333
Memory usage before including subclasses: 5684416
Memory usage after including subclasses: 5692224 (difference: 7808)

$ curl http://$HOSTNAME/1.php?bytes=1
Memory usage before including subclasses: 232696
Memory usage after including subclasses: 242024 (difference: 9328)
                                         ^^^^^^              ^^^^


Actual result:
--------------
The change in memory usage is large, because APC is storing a copy of the str_repeat with each cached derived class.

$ curl http://$HOSTNAME/1.php?clear
Clearing opcode cache.

$ curl http://$HOSTNAME/1.php?bytes=5444333
Memory usage before including subclasses: 5684032
Memory usage after including subclasses: 5691840 (difference: 7808)

$ curl http://$HOSTNAME/1.php?bytes=1
Memory usage before including subclasses: 233080
Memory usage after including subclasses: 43796968 (difference: 43563888)
                                         ^^^^^^^^              ^^^^^^^^


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-09-13 00:02 UTC] rasmus@php.net
-Status: Open +Status: Suspended
 [2013-09-13 00:02 UTC] rasmus@php.net
While that might be possible, I'd have to look into it, I don't see it happening. 
I suspect it would be a large effort and the opcode cache development focus has 
moved to OPCache. I don't see any large new things being added to APC.
 [2013-09-18 13:24 UTC] gopalv@php.net
I think most of the eyes have moved onto opcache now.

I doubt this will be fixed in APC mostly because there's unlikely to be another stable release out for it.
 [2013-09-18 15:03 UTC] askalski at gmail dot com
Thanks for the followup.  I hadn't realized that a standalone version Opcache had been released for 5.2 through 5.4 - I'm in the process of testing it now, and so far everything looks good.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Wed Nov 13 22:01:29 2019 UTC