While cleaning out obsolete StringTable entries, StringTable::unlink_or_oops_do() calculates the number of dead entries encountered to calculate a dead ratio to eventually signal the ServiceThread to clean out those entries.
This number of dead entries is calculated by the number of entries not passing the IsAlive check in OopStorage::weak_oops_do(). However this disregards the number of already dead entries in the StringTable as they are filtered out even earlier, so the calculated ratio may be too small - so if the ServiceThread does not get to cleaning out StringTable entries between two gcs, dead entries will accumulate over time.
This may result in that the dead ratio will never be taken into account when cleaning out the table, only occurring when the load factor of the StringTable gets too large.
Found during the review to JDK-8213229.
ZGC is not affected as it uses OopStorage::oops_do() which does not skip NULL (i.e. dead) entries to iterate over the OopStorage concurrently.