mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8372150: Parallel: Tighten requirements around heap sizes with NUMA and Large Pages
Reviewed-by: ayang, stefank, aboldtch, stuefe
This commit is contained in:
parent
1f417e7761
commit
4ac3395634
@ -37,8 +37,45 @@
|
||||
#include "utilities/defaultStream.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
size_t ParallelArguments::conservative_max_heap_alignment() {
|
||||
return compute_heap_alignment();
|
||||
static size_t num_young_spaces() {
|
||||
// When using NUMA, we create one MutableNUMASpace for each NUMA node
|
||||
const size_t num_eden_spaces = UseNUMA ? os::numa_get_groups_num() : 1;
|
||||
|
||||
// The young generation must have room for eden + two survivors
|
||||
return num_eden_spaces + 2;
|
||||
}
|
||||
|
||||
static size_t num_old_spaces() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ParallelArguments::initialize_alignments() {
|
||||
// Initialize card size before initializing alignments
|
||||
CardTable::initialize_card_size();
|
||||
const size_t card_table_alignment = CardTable::ct_max_alignment_constraint();
|
||||
SpaceAlignment = ParallelScavengeHeap::default_space_alignment();
|
||||
|
||||
if (UseLargePages) {
|
||||
const size_t total_spaces = num_young_spaces() + num_old_spaces();
|
||||
const size_t page_size = os::page_size_for_region_unaligned(MaxHeapSize, total_spaces);
|
||||
ParallelScavengeHeap::set_desired_page_size(page_size);
|
||||
|
||||
if (page_size == os::vm_page_size()) {
|
||||
log_warning(gc, heap)("MaxHeapSize (%zu) must be large enough for %zu * page-size; Disabling UseLargePages for heap",
|
||||
MaxHeapSize, total_spaces);
|
||||
}
|
||||
|
||||
if (page_size > SpaceAlignment) {
|
||||
SpaceAlignment = page_size;
|
||||
}
|
||||
|
||||
HeapAlignment = lcm(page_size, card_table_alignment);
|
||||
|
||||
} else {
|
||||
assert(is_aligned(SpaceAlignment, os::vm_page_size()), "");
|
||||
ParallelScavengeHeap::set_desired_page_size(os::vm_page_size());
|
||||
HeapAlignment = card_table_alignment;
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelArguments::initialize() {
|
||||
@ -98,49 +135,36 @@ void ParallelArguments::initialize() {
|
||||
FullGCForwarding::initialize_flags(heap_reserved_size_bytes());
|
||||
}
|
||||
|
||||
void ParallelArguments::initialize_alignments() {
|
||||
// Initialize card size before initializing alignments
|
||||
CardTable::initialize_card_size();
|
||||
SpaceAlignment = ParallelScavengeHeap::default_space_alignment();
|
||||
HeapAlignment = compute_heap_alignment();
|
||||
}
|
||||
size_t ParallelArguments::conservative_max_heap_alignment() {
|
||||
// The card marking array and the offset arrays for old generations are
|
||||
// committed in os pages as well. Make sure they are entirely full (to
|
||||
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
||||
// byte entry and the os page size is 4096, the maximum heap size should
|
||||
// be 512*4096 = 2MB aligned.
|
||||
|
||||
void ParallelArguments::initialize_heap_flags_and_sizes_one_pass() {
|
||||
// Do basic sizing work
|
||||
GenArguments::initialize_heap_flags_and_sizes();
|
||||
}
|
||||
size_t alignment = CardTable::ct_max_alignment_constraint();
|
||||
|
||||
void ParallelArguments::initialize_heap_flags_and_sizes() {
|
||||
initialize_heap_flags_and_sizes_one_pass();
|
||||
|
||||
if (!UseLargePages) {
|
||||
ParallelScavengeHeap::set_desired_page_size(os::vm_page_size());
|
||||
return;
|
||||
if (UseLargePages) {
|
||||
// In presence of large pages we have to make sure that our
|
||||
// alignment is large page aware.
|
||||
alignment = lcm(os::large_page_size(), alignment);
|
||||
}
|
||||
|
||||
// If using large-page, need to update SpaceAlignment so that spaces are page-size aligned.
|
||||
const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
|
||||
const size_t page_sz = os::page_size_for_region_aligned(MinHeapSize, min_pages);
|
||||
ParallelScavengeHeap::set_desired_page_size(page_sz);
|
||||
|
||||
if (page_sz == os::vm_page_size()) {
|
||||
log_warning(gc, heap)("MinHeapSize (%zu) must be large enough for 4 * page-size; Disabling UseLargePages for heap", MinHeapSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// Space is largepage-aligned.
|
||||
size_t new_alignment = page_sz;
|
||||
if (new_alignment != SpaceAlignment) {
|
||||
SpaceAlignment = new_alignment;
|
||||
// Redo everything from the start
|
||||
initialize_heap_flags_and_sizes_one_pass();
|
||||
}
|
||||
}
|
||||
|
||||
size_t ParallelArguments::heap_reserved_size_bytes() {
|
||||
return MaxHeapSize;
|
||||
return alignment;
|
||||
}
|
||||
|
||||
CollectedHeap* ParallelArguments::create_heap() {
|
||||
return new ParallelScavengeHeap();
|
||||
}
|
||||
|
||||
size_t ParallelArguments::young_gen_size_lower_bound() {
|
||||
return num_young_spaces() * SpaceAlignment;
|
||||
}
|
||||
|
||||
size_t ParallelArguments::old_gen_size_lower_bound() {
|
||||
return num_old_spaces() * SpaceAlignment;
|
||||
}
|
||||
|
||||
size_t ParallelArguments::heap_reserved_size_bytes() {
|
||||
return MaxHeapSize;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,21 +26,16 @@
|
||||
#ifndef SHARE_GC_PARALLEL_PARALLELARGUMENTS_HPP
|
||||
#define SHARE_GC_PARALLEL_PARALLELARGUMENTS_HPP
|
||||
|
||||
#include "gc/shared/gcArguments.hpp"
|
||||
#include "gc/shared/genArguments.hpp"
|
||||
|
||||
class CollectedHeap;
|
||||
|
||||
class ParallelArguments : public GenArguments {
|
||||
private:
|
||||
virtual void initialize_alignments();
|
||||
virtual void initialize_heap_flags_and_sizes();
|
||||
|
||||
void initialize_heap_flags_and_sizes_one_pass();
|
||||
|
||||
virtual void initialize();
|
||||
virtual size_t conservative_max_heap_alignment();
|
||||
virtual CollectedHeap* create_heap();
|
||||
virtual size_t young_gen_size_lower_bound();
|
||||
virtual size_t old_gen_size_lower_bound();
|
||||
|
||||
public:
|
||||
static size_t heap_reserved_size_bytes();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,11 +28,49 @@
|
||||
#include "gc/shared/fullGCForwarding.hpp"
|
||||
#include "gc/shared/gcArguments.hpp"
|
||||
|
||||
static size_t compute_heap_alignment() {
|
||||
// The card marking array and the offset arrays for old generations are
|
||||
// committed in os pages as well. Make sure they are entirely full (to
|
||||
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
||||
// byte entry and the os page size is 4096, the maximum heap size should
|
||||
// be 512*4096 = 2MB aligned.
|
||||
|
||||
size_t alignment = CardTable::ct_max_alignment_constraint();
|
||||
|
||||
if (UseLargePages) {
|
||||
// In presence of large pages we have to make sure that our
|
||||
// alignment is large page aware.
|
||||
alignment = lcm(os::large_page_size(), alignment);
|
||||
}
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
void SerialArguments::initialize_alignments() {
|
||||
// Initialize card size before initializing alignments
|
||||
CardTable::initialize_card_size();
|
||||
SpaceAlignment = (size_t)Generation::GenGrain;
|
||||
HeapAlignment = compute_heap_alignment();
|
||||
}
|
||||
|
||||
void SerialArguments::initialize() {
|
||||
GCArguments::initialize();
|
||||
FullGCForwarding::initialize_flags(MaxHeapSize);
|
||||
}
|
||||
|
||||
size_t SerialArguments::conservative_max_heap_alignment() {
|
||||
return MAX2((size_t)Generation::GenGrain, compute_heap_alignment());
|
||||
}
|
||||
|
||||
CollectedHeap* SerialArguments::create_heap() {
|
||||
return new SerialHeap();
|
||||
}
|
||||
|
||||
size_t SerialArguments::young_gen_size_lower_bound() {
|
||||
// The young generation must be aligned and have room for eden + two survivors
|
||||
return 3 * SpaceAlignment;
|
||||
}
|
||||
|
||||
size_t SerialArguments::old_gen_size_lower_bound() {
|
||||
return SpaceAlignment;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,12 +28,14 @@
|
||||
|
||||
#include "gc/shared/genArguments.hpp"
|
||||
|
||||
class CollectedHeap;
|
||||
|
||||
class SerialArguments : public GenArguments {
|
||||
private:
|
||||
virtual void initialize_alignments();
|
||||
virtual void initialize();
|
||||
virtual size_t conservative_max_heap_alignment();
|
||||
virtual CollectedHeap* create_heap();
|
||||
virtual size_t young_gen_size_lower_bound();
|
||||
virtual size_t old_gen_size_lower_bound();
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_SERIAL_SERIALARGUMENTS_HPP
|
||||
|
||||
@ -62,24 +62,6 @@ void GCArguments::initialize_heap_sizes() {
|
||||
initialize_size_info();
|
||||
}
|
||||
|
||||
size_t GCArguments::compute_heap_alignment() {
|
||||
// The card marking array and the offset arrays for old generations are
|
||||
// committed in os pages as well. Make sure they are entirely full (to
|
||||
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
||||
// byte entry and the os page size is 4096, the maximum heap size should
|
||||
// be 512*4096 = 2MB aligned.
|
||||
|
||||
size_t alignment = CardTable::ct_max_alignment_constraint();
|
||||
|
||||
if (UseLargePages) {
|
||||
// In presence of large pages we have to make sure that our
|
||||
// alignment is large page aware.
|
||||
alignment = lcm(os::large_page_size(), alignment);
|
||||
}
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void GCArguments::assert_flags() {
|
||||
assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");
|
||||
|
||||
@ -45,6 +45,8 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void initialize();
|
||||
|
||||
// Return the (conservative) maximum heap alignment
|
||||
virtual size_t conservative_max_heap_alignment() = 0;
|
||||
|
||||
// Used by heap size heuristics to determine max
|
||||
@ -59,8 +61,6 @@ public:
|
||||
}
|
||||
|
||||
void initialize_heap_sizes();
|
||||
|
||||
static size_t compute_heap_alignment();
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_SHARED_GCARGUMENTS_HPP
|
||||
|
||||
@ -42,17 +42,6 @@ size_t MaxOldSize = 0;
|
||||
// See more in JDK-8346005
|
||||
size_t OldSize = ScaleForWordSize(4*M);
|
||||
|
||||
size_t GenArguments::conservative_max_heap_alignment() { return (size_t)Generation::GenGrain; }
|
||||
|
||||
static size_t young_gen_size_lower_bound() {
|
||||
// The young generation must be aligned and have room for eden + two survivors
|
||||
return 3 * SpaceAlignment;
|
||||
}
|
||||
|
||||
static size_t old_gen_size_lower_bound() {
|
||||
return SpaceAlignment;
|
||||
}
|
||||
|
||||
size_t GenArguments::scale_by_NewRatio_aligned(size_t base_size, size_t alignment) {
|
||||
return align_down_bounded(base_size / (NewRatio + 1), alignment);
|
||||
}
|
||||
@ -64,13 +53,6 @@ static size_t bound_minus_alignment(size_t desired_size,
|
||||
return MIN2(desired_size, max_minus);
|
||||
}
|
||||
|
||||
void GenArguments::initialize_alignments() {
|
||||
// Initialize card size before initializing alignments
|
||||
CardTable::initialize_card_size();
|
||||
SpaceAlignment = (size_t)Generation::GenGrain;
|
||||
HeapAlignment = compute_heap_alignment();
|
||||
}
|
||||
|
||||
void GenArguments::initialize_heap_flags_and_sizes() {
|
||||
GCArguments::initialize_heap_flags_and_sizes();
|
||||
|
||||
|
||||
@ -38,17 +38,16 @@ extern size_t OldSize;
|
||||
class GenArguments : public GCArguments {
|
||||
friend class TestGenCollectorPolicy; // Testing
|
||||
private:
|
||||
virtual void initialize_alignments();
|
||||
virtual void initialize_size_info();
|
||||
|
||||
// Return the (conservative) maximum heap alignment
|
||||
virtual size_t conservative_max_heap_alignment();
|
||||
|
||||
DEBUG_ONLY(void assert_flags();)
|
||||
DEBUG_ONLY(void assert_size_info();)
|
||||
|
||||
static size_t scale_by_NewRatio_aligned(size_t base_size, size_t alignment);
|
||||
|
||||
virtual size_t young_gen_size_lower_bound() = 0;
|
||||
virtual size_t old_gen_size_lower_bound() = 0;
|
||||
|
||||
protected:
|
||||
virtual void initialize_heap_flags_and_sizes();
|
||||
};
|
||||
|
||||
@ -250,7 +250,7 @@ static JVMFlag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bo
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
heap_alignment = GCArguments::compute_heap_alignment();
|
||||
heap_alignment = Arguments::conservative_max_heap_alignment();
|
||||
}
|
||||
|
||||
return MaxSizeForAlignment(name, value, heap_alignment, verbose);
|
||||
|
||||
@ -1478,10 +1478,9 @@ void Arguments::set_conservative_max_heap_alignment() {
|
||||
// the alignments imposed by several sources: any requirements from the heap
|
||||
// itself and the maximum page size we may run the VM with.
|
||||
size_t heap_alignment = GCConfig::arguments()->conservative_max_heap_alignment();
|
||||
_conservative_max_heap_alignment = MAX4(heap_alignment,
|
||||
_conservative_max_heap_alignment = MAX3(heap_alignment,
|
||||
os::vm_allocation_granularity(),
|
||||
os::max_page_size(),
|
||||
GCArguments::compute_heap_alignment());
|
||||
os::max_page_size());
|
||||
assert(is_power_of_2(_conservative_max_heap_alignment), "Expected to be a power-of-2");
|
||||
}
|
||||
|
||||
|
||||
@ -140,17 +140,6 @@ class TestGenCollectorPolicy {
|
||||
ASSERT_EQ(param, NewSize);
|
||||
}
|
||||
};
|
||||
|
||||
class SetMaxNewSizeCmd : public BinaryExecutor {
|
||||
public:
|
||||
SetMaxNewSizeCmd(size_t param1, size_t param2) : BinaryExecutor(param1, param2) { }
|
||||
void execute() {
|
||||
size_t heap_alignment = GCArguments::compute_heap_alignment();
|
||||
size_t new_size_value = align_up(MaxHeapSize, heap_alignment)
|
||||
- param1 + param2;
|
||||
FLAG_SET_CMDLINE(MaxNewSize, new_size_value);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user