mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8366147: ZGC: ZPageAllocator::cleanup_failed_commit_single_partition may leak memory
Reviewed-by: stefank, sjohanss, jsikstro
This commit is contained in:
parent
a2da75a6b6
commit
86d6a2e05e
@ -1092,7 +1092,8 @@ void ZPartition::free_memory_alloc_failed(ZMemoryAllocation* allocation) {
|
||||
freed += vmem.size();
|
||||
_cache.insert(vmem);
|
||||
}
|
||||
assert(allocation->harvested() + allocation->committed_capacity() == freed, "must have freed all");
|
||||
assert(allocation->harvested() + allocation->committed_capacity() == freed, "must have freed all"
|
||||
" %zu + %zu == %zu", allocation->harvested(), allocation->committed_capacity(), freed);
|
||||
|
||||
// Adjust capacity to reflect the failed capacity increase
|
||||
const size_t remaining = allocation->size() - freed;
|
||||
@ -1909,23 +1910,27 @@ void ZPageAllocator::cleanup_failed_commit_single_partition(ZSinglePartitionAllo
|
||||
ZMemoryAllocation* const allocation = single_partition_allocation->allocation();
|
||||
|
||||
assert(allocation->commit_failed(), "Must have failed to commit");
|
||||
assert(allocation->partial_vmems()->is_empty(), "Invariant for single partition commit failure");
|
||||
|
||||
const size_t committed = allocation->committed_capacity();
|
||||
const ZVirtualMemory non_harvested_vmem = vmem.last_part(allocation->harvested());
|
||||
const ZVirtualMemory committed_vmem = non_harvested_vmem.first_part(committed);
|
||||
const ZVirtualMemory non_committed_vmem = non_harvested_vmem.last_part(committed);
|
||||
// For a single partition we have unmapped the harvested memory before we
|
||||
// started committing, and moved its physical memory association to the start
|
||||
// of the vmem. As such, the partial_vmems is empty. All the harvested and
|
||||
// partially successfully committed memory is mapped in the first part of vmem.
|
||||
const size_t harvested_and_committed_capacity = allocation->harvested() + allocation->committed_capacity();
|
||||
const ZVirtualMemory succeeded_vmem = vmem.first_part(harvested_and_committed_capacity);
|
||||
const ZVirtualMemory failed_vmem = vmem.last_part(harvested_and_committed_capacity);
|
||||
|
||||
if (committed_vmem.size() > 0) {
|
||||
if (succeeded_vmem.size() > 0) {
|
||||
// Register the committed and mapped memory. We insert the committed
|
||||
// memory into partial_vmems so that it will be inserted into the cache
|
||||
// in a subsequent step.
|
||||
allocation->partial_vmems()->append(committed_vmem);
|
||||
allocation->partial_vmems()->append(succeeded_vmem);
|
||||
}
|
||||
|
||||
// Free the virtual and physical memory we fetched to use but failed to commit
|
||||
ZPartition& partition = allocation->partition();
|
||||
partition.free_physical(non_committed_vmem);
|
||||
partition.free_virtual(non_committed_vmem);
|
||||
partition.free_physical(failed_vmem);
|
||||
partition.free_virtual(failed_vmem);
|
||||
}
|
||||
|
||||
void ZPageAllocator::cleanup_failed_commit_multi_partition(ZMultiPartitionAllocation* multi_partition_allocation, const ZVirtualMemory& vmem) {
|
||||
|
||||
@ -23,6 +23,14 @@
|
||||
|
||||
package gc.z;
|
||||
|
||||
/*
|
||||
* @test id=Normal
|
||||
* @requires vm.gc.Z & vm.debug
|
||||
* @summary Test ZGC graceful failure when a commit fails
|
||||
* @library / /test/lib
|
||||
* @run driver gc.z.TestCommitFailure
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test id=ZFakeNUMA
|
||||
* @requires vm.gc.Z & vm.debug
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user