Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
b888cc0d
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b888cc0d
编写于
1月 27, 2014
作者:
B
brutisso
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8030177: G1: Enable TLAB resizing
Reviewed-by: tschatzl, stefank, jmasa
上级
583b4f86
变更
20
隐藏空白更改
内联
并排
Showing
20 changed file
with
141 addition
and
74 deletion
+141
-74
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
...pot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+17
-4
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
...pot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+6
-4
hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
...t/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+2
-0
hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
..._implementation/parallelScavenge/parallelScavengeHeap.cpp
+4
-0
hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
..._implementation/parallelScavenge/parallelScavengeHeap.hpp
+1
-0
hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
...rc/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
+20
-0
hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
...rc/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
+1
-0
hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
...ot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
+1
-0
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
...rc/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
+4
-0
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
...rc/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
+1
-10
hotspot/src/share/vm/gc_interface/collectedHeap.cpp
hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+15
-0
hotspot/src/share/vm/gc_interface/collectedHeap.hpp
hotspot/src/share/vm/gc_interface/collectedHeap.hpp
+9
-7
hotspot/src/share/vm/memory/defNewGeneration.cpp
hotspot/src/share/vm/memory/defNewGeneration.cpp
+4
-0
hotspot/src/share/vm/memory/defNewGeneration.hpp
hotspot/src/share/vm/memory/defNewGeneration.hpp
+1
-0
hotspot/src/share/vm/memory/genCollectedHeap.cpp
hotspot/src/share/vm/memory/genCollectedHeap.cpp
+10
-0
hotspot/src/share/vm/memory/genCollectedHeap.hpp
hotspot/src/share/vm/memory/genCollectedHeap.hpp
+1
-0
hotspot/src/share/vm/memory/generation.hpp
hotspot/src/share/vm/memory/generation.hpp
+4
-0
hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp
hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp
+33
-47
hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
+5
-2
hotspot/src/share/vm/memory/universe.cpp
hotspot/src/share/vm/memory/universe.cpp
+2
-0
未找到文件。
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
b888cc0d
...
...
@@ -2996,7 +2996,17 @@ bool G1CollectedHeap::supports_tlab_allocation() const {
}
size_t
G1CollectedHeap
::
tlab_capacity
(
Thread
*
ignored
)
const
{
return
HeapRegion
::
GrainBytes
;
return
(
_g1_policy
->
young_list_target_length
()
-
young_list
()
->
survivor_length
())
*
HeapRegion
::
GrainBytes
;
}
size_t
G1CollectedHeap
::
tlab_used
(
Thread
*
ignored
)
const
{
return
young_list
()
->
eden_used_bytes
();
}
// For G1 TLABs should not contain humongous objects, so the maximum TLAB size
// must be smaller than the humongous object limit.
size_t
G1CollectedHeap
::
max_tlab_size
()
const
{
return
align_size_down
(
_humongous_object_threshold_in_words
-
1
,
MinObjAlignment
);
}
size_t
G1CollectedHeap
::
unsafe_max_tlab_alloc
(
Thread
*
ignored
)
const
{
...
...
@@ -3008,11 +3018,11 @@ size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
// humongous objects.
HeapRegion
*
hr
=
_mutator_alloc_region
.
get
();
size_t
max_tlab
_size
=
_humongous_object_threshold_in_words
*
wordSize
;
size_t
max_tlab
=
max_tlab_size
()
*
wordSize
;
if
(
hr
==
NULL
)
{
return
max_tlab
_size
;
return
max_tlab
;
}
else
{
return
MIN2
(
MAX2
(
hr
->
free
(),
(
size_t
)
MinTLABSize
),
max_tlab
_size
);
return
MIN2
(
MAX2
(
hr
->
free
(),
(
size_t
)
MinTLABSize
),
max_tlab
);
}
}
...
...
@@ -3649,6 +3659,7 @@ void G1CollectedHeap::gc_prologue(bool full /* Ignored */) {
// always_do_update_barrier = false;
assert
(
InlineCacheBuffer
::
is_empty
(),
"should have cleaned up ICBuffer"
);
// Fill TLAB's and such
accumulate_statistics_all_tlabs
();
ensure_parsability
(
true
);
if
(
G1SummarizeRSetStats
&&
(
G1SummarizeRSetStatsPeriod
>
0
)
&&
...
...
@@ -3673,6 +3684,8 @@ void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
"derived pointer present"
));
// always_do_update_barrier = true;
resize_all_tlabs
();
// We have just completed a GC. Update the soft reference
// policy with the new heap occupancy
Universe
::
update_heap_info_at_gc
();
...
...
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
浏览文件 @
b888cc0d
...
...
@@ -1470,9 +1470,11 @@ public:
// Section on thread-local allocation buffers (TLABs)
// See CollectedHeap for semantics.
virtual
bool
supports_tlab_allocation
()
const
;
virtual
size_t
tlab_capacity
(
Thread
*
thr
)
const
;
virtual
size_t
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
;
bool
supports_tlab_allocation
()
const
;
size_t
tlab_capacity
(
Thread
*
ignored
)
const
;
size_t
tlab_used
(
Thread
*
ignored
)
const
;
size_t
max_tlab_size
()
const
;
size_t
unsafe_max_tlab_alloc
(
Thread
*
ignored
)
const
;
// Can a compiler initialize a new object without store barriers?
// This permission only extends from the creation of a new object
...
...
@@ -1557,7 +1559,7 @@ public:
void
set_region_short_lived_locked
(
HeapRegion
*
hr
);
// add appropriate methods for any other surv rate groups
YoungList
*
young_list
()
{
return
_young_list
;
}
YoungList
*
young_list
()
const
{
return
_young_list
;
}
// debugging
bool
check_young_list_well_formed
()
{
...
...
hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
浏览文件 @
b888cc0d
...
...
@@ -820,6 +820,8 @@ public:
// do that for any other surv rate groups
}
size_t
young_list_target_length
()
const
{
return
_young_list_target_length
;
}
bool
is_young_list_full
()
{
uint
young_list_length
=
_g1
->
young_list
()
->
length
();
uint
young_list_target_length
=
_young_list_target_length
;
...
...
hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
浏览文件 @
b888cc0d
...
...
@@ -488,6 +488,10 @@ size_t ParallelScavengeHeap::tlab_capacity(Thread* thr) const {
return
young_gen
()
->
eden_space
()
->
tlab_capacity
(
thr
);
}
size_t
ParallelScavengeHeap
::
tlab_used
(
Thread
*
thr
)
const
{
return
young_gen
()
->
eden_space
()
->
tlab_used
(
thr
);
}
size_t
ParallelScavengeHeap
::
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
{
return
young_gen
()
->
eden_space
()
->
unsafe_max_tlab_alloc
(
thr
);
}
...
...
hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
浏览文件 @
b888cc0d
...
...
@@ -187,6 +187,7 @@ class ParallelScavengeHeap : public CollectedHeap {
bool
supports_tlab_allocation
()
const
{
return
true
;
}
size_t
tlab_capacity
(
Thread
*
thr
)
const
;
size_t
tlab_used
(
Thread
*
thr
)
const
;
size_t
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
;
// Can a compiler initialize a new object without store barriers?
...
...
hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
浏览文件 @
b888cc0d
...
...
@@ -173,6 +173,26 @@ size_t MutableNUMASpace::tlab_capacity(Thread *thr) const {
return
lgrp_spaces
()
->
at
(
i
)
->
space
()
->
capacity_in_bytes
();
}
size_t
MutableNUMASpace
::
tlab_used
(
Thread
*
thr
)
const
{
// Please see the comments for tlab_capacity().
guarantee
(
thr
!=
NULL
,
"No thread"
);
int
lgrp_id
=
thr
->
lgrp_id
();
if
(
lgrp_id
==
-
1
)
{
if
(
lgrp_spaces
()
->
length
()
>
0
)
{
return
(
used_in_bytes
())
/
lgrp_spaces
()
->
length
();
}
else
{
assert
(
false
,
"There should be at least one locality group"
);
return
0
;
}
}
int
i
=
lgrp_spaces
()
->
find
(
&
lgrp_id
,
LGRPSpace
::
equals
);
if
(
i
==
-
1
)
{
return
0
;
}
return
lgrp_spaces
()
->
at
(
i
)
->
space
()
->
used_in_bytes
();
}
size_t
MutableNUMASpace
::
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
{
// Please see the comments for tlab_capacity().
guarantee
(
thr
!=
NULL
,
"No thread"
);
...
...
hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
浏览文件 @
b888cc0d
...
...
@@ -217,6 +217,7 @@ class MutableNUMASpace : public MutableSpace {
using
MutableSpace
::
capacity_in_words
;
virtual
size_t
capacity_in_words
(
Thread
*
thr
)
const
;
virtual
size_t
tlab_capacity
(
Thread
*
thr
)
const
;
virtual
size_t
tlab_used
(
Thread
*
thr
)
const
;
virtual
size_t
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
;
// Allocation (return NULL if full)
...
...
hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
浏览文件 @
b888cc0d
...
...
@@ -124,6 +124,7 @@ class MutableSpace: public ImmutableSpace {
virtual
size_t
used_in_words
()
const
{
return
pointer_delta
(
top
(),
bottom
());
}
virtual
size_t
free_in_words
()
const
{
return
pointer_delta
(
end
(),
top
());
}
virtual
size_t
tlab_capacity
(
Thread
*
thr
)
const
{
return
capacity_in_bytes
();
}
virtual
size_t
tlab_used
(
Thread
*
thr
)
const
{
return
used_in_bytes
();
}
virtual
size_t
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
{
return
free_in_bytes
();
}
// Allocation (return NULL if full)
...
...
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
浏览文件 @
b888cc0d
...
...
@@ -89,6 +89,10 @@ void ParGCAllocBuffer::flush_stats(PLABStats* stats) {
// scavenge; it clears the sensor accumulators.
void
PLABStats
::
adjust_desired_plab_sz
(
uint
no_of_gc_workers
)
{
assert
(
ResizePLAB
,
"Not set"
);
assert
(
is_object_aligned
(
max_size
())
&&
min_size
()
<=
max_size
(),
"PLAB clipping computation may be incorrect"
);
if
(
_allocated
==
0
)
{
assert
(
_unused
==
0
,
err_msg
(
"Inconsistency in PLAB stats: "
...
...
hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
浏览文件 @
b888cc0d
...
...
@@ -181,16 +181,7 @@ class PLABStats VALUE_OBJ_CLASS_SPEC {
_used
(
0
),
_desired_plab_sz
(
desired_plab_sz_
),
_filter
(
wt
)
{
size_t
min_sz
=
min_size
();
size_t
max_sz
=
max_size
();
size_t
aligned_min_sz
=
align_object_size
(
min_sz
);
size_t
aligned_max_sz
=
align_object_size
(
max_sz
);
assert
(
min_sz
<=
aligned_min_sz
&&
max_sz
>=
aligned_max_sz
&&
min_sz
<=
max_sz
,
"PLAB clipping computation in adjust_desired_plab_sz()"
" may be incorrect"
);
}
{
}
static
const
size_t
min_size
()
{
return
ParGCAllocBuffer
::
min_size
();
...
...
hotspot/src/share/vm/gc_interface/collectedHeap.cpp
浏览文件 @
b888cc0d
...
...
@@ -320,6 +320,21 @@ void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) {
assert
(
thread
->
deferred_card_mark
().
is_empty
(),
"invariant"
);
}
size_t
CollectedHeap
::
max_tlab_size
()
const
{
// TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE].
// This restriction could be removed by enabling filling with multiple arrays.
// If we compute that the reasonable way as
// header_size + ((sizeof(jint) * max_jint) / HeapWordSize)
// we'll overflow on the multiply, so we do the divide first.
// We actually lose a little by dividing first,
// but that just makes the TLAB somewhat smaller than the biggest array,
// which is fine, since we'll be able to fill that.
size_t
max_int_size
=
typeArrayOopDesc
::
header_size
(
T_INT
)
+
sizeof
(
jint
)
*
((
juint
)
max_jint
/
(
size_t
)
HeapWordSize
);
return
align_size_down
(
max_int_size
,
MinObjAlignment
);
}
// Helper for ReduceInitialCardMarks. For performance,
// compiled code may elide card-marks for initializing stores
// to a newly allocated object along the fast-path. We
...
...
hotspot/src/share/vm/gc_interface/collectedHeap.hpp
浏览文件 @
b888cc0d
...
...
@@ -394,14 +394,16 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// the following methods:
// Returns "true" iff the heap supports thread-local allocation buffers.
// The default is "no".
virtual
bool
supports_tlab_allocation
()
const
{
return
false
;
}
virtual
bool
supports_tlab_allocation
()
const
=
0
;
// The amount of space available for thread-local allocation buffers.
virtual
size_t
tlab_capacity
(
Thread
*
thr
)
const
{
guarantee
(
false
,
"thread-local allocation buffers not supported"
);
return
0
;
}
virtual
size_t
tlab_capacity
(
Thread
*
thr
)
const
=
0
;
// The amount of used space for thread-local allocation buffers for the given thread.
virtual
size_t
tlab_used
(
Thread
*
thr
)
const
=
0
;
virtual
size_t
max_tlab_size
()
const
;
// An estimate of the maximum allocation that could be performed
// for thread-local allocation buffers without triggering any
// collection or expansion activity.
...
...
hotspot/src/share/vm/memory/defNewGeneration.cpp
浏览文件 @
b888cc0d
...
...
@@ -1084,6 +1084,10 @@ size_t DefNewGeneration::tlab_capacity() const {
return
eden
()
->
capacity
();
}
size_t
DefNewGeneration
::
tlab_used
()
const
{
return
eden
()
->
used
();
}
size_t
DefNewGeneration
::
unsafe_max_tlab_alloc
()
const
{
return
unsafe_max_alloc_nogc
();
}
hotspot/src/share/vm/memory/defNewGeneration.hpp
浏览文件 @
b888cc0d
...
...
@@ -239,6 +239,7 @@ protected:
// Thread-local allocation buffers
bool
supports_tlab_allocation
()
const
{
return
true
;
}
size_t
tlab_capacity
()
const
;
size_t
tlab_used
()
const
;
size_t
unsafe_max_tlab_alloc
()
const
;
// Grow the generation by the specified number of bytes.
...
...
hotspot/src/share/vm/memory/genCollectedHeap.cpp
浏览文件 @
b888cc0d
...
...
@@ -932,6 +932,16 @@ size_t GenCollectedHeap::tlab_capacity(Thread* thr) const {
return
result
;
}
size_t
GenCollectedHeap
::
tlab_used
(
Thread
*
thr
)
const
{
size_t
result
=
0
;
for
(
int
i
=
0
;
i
<
_n_gens
;
i
+=
1
)
{
if
(
_gens
[
i
]
->
supports_tlab_allocation
())
{
result
+=
_gens
[
i
]
->
tlab_used
();
}
}
return
result
;
}
size_t
GenCollectedHeap
::
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
{
size_t
result
=
0
;
for
(
int
i
=
0
;
i
<
_n_gens
;
i
+=
1
)
{
...
...
hotspot/src/share/vm/memory/genCollectedHeap.hpp
浏览文件 @
b888cc0d
...
...
@@ -248,6 +248,7 @@ public:
// Section on TLAB's.
virtual
bool
supports_tlab_allocation
()
const
;
virtual
size_t
tlab_capacity
(
Thread
*
thr
)
const
;
virtual
size_t
tlab_used
(
Thread
*
thr
)
const
;
virtual
size_t
unsafe_max_tlab_alloc
(
Thread
*
thr
)
const
;
virtual
HeapWord
*
allocate_new_tlab
(
size_t
size
);
...
...
hotspot/src/share/vm/memory/generation.hpp
浏览文件 @
b888cc0d
...
...
@@ -299,6 +299,10 @@ class Generation: public CHeapObj<mtGC> {
guarantee
(
false
,
"Generation doesn't support thread local allocation buffers"
);
return
0
;
}
virtual
size_t
tlab_used
()
const
{
guarantee
(
false
,
"Generation doesn't support thread local allocation buffers"
);
return
0
;
}
virtual
size_t
unsafe_max_tlab_alloc
()
const
{
guarantee
(
false
,
"Generation doesn't support thread local allocation buffers"
);
return
0
;
...
...
hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp
浏览文件 @
b888cc0d
...
...
@@ -34,6 +34,7 @@
// Thread-Local Edens support
// static member initialization
size_t
ThreadLocalAllocBuffer
::
_max_size
=
0
;
unsigned
ThreadLocalAllocBuffer
::
_target_refills
=
0
;
GlobalTLABStats
*
ThreadLocalAllocBuffer
::
_global_stats
=
NULL
;
...
...
@@ -45,7 +46,7 @@ void ThreadLocalAllocBuffer::clear_before_allocation() {
void
ThreadLocalAllocBuffer
::
accumulate_statistics_before_gc
()
{
global_stats
()
->
initialize
();
for
(
JavaThread
*
thread
=
Threads
::
first
();
thread
;
thread
=
thread
->
next
())
{
for
(
JavaThread
*
thread
=
Threads
::
first
();
thread
!=
NULL
;
thread
=
thread
->
next
())
{
thread
->
tlab
().
accumulate_statistics
();
thread
->
tlab
().
initialize_statistics
();
}
...
...
@@ -60,28 +61,32 @@ void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
}
void
ThreadLocalAllocBuffer
::
accumulate_statistics
()
{
size_t
capacity
=
Universe
::
heap
()
->
tlab_capacity
(
myThread
())
/
HeapWordSize
;
size_t
unused
=
Universe
::
heap
()
->
unsafe_max_tlab_alloc
(
myThread
())
/
HeapWordSize
;
size_t
used
=
capacity
-
unused
;
// Update allocation history if a reasonable amount of eden was allocated.
bool
update_allocation_history
=
used
>
0.5
*
capacity
;
Thread
*
thread
=
myThread
();
size_t
capacity
=
Universe
::
heap
()
->
tlab_capacity
(
thread
);
size_t
used
=
Universe
::
heap
()
->
tlab_used
(
thread
);
_gc_waste
+=
(
unsigned
)
remaining
();
size_t
total_allocated
=
thread
->
allocated_bytes
();
size_t
allocated_since_last_gc
=
total_allocated
-
_allocated_before_last_gc
;
_allocated_before_last_gc
=
total_allocated
;
if
(
PrintTLAB
&&
(
_number_of_refills
>
0
||
Verbose
))
{
print_stats
(
"gc"
);
}
if
(
_number_of_refills
>
0
)
{
// Update allocation history if a reasonable amount of eden was allocated.
bool
update_allocation_history
=
used
>
0.5
*
capacity
;
if
(
update_allocation_history
)
{
// Average the fraction of eden allocated in a tlab by this
// thread for use in the next resize operation.
// _gc_waste is not subtracted because it's included in
// "used".
size_t
allocation
=
_number_of_refills
*
desired_size
();
double
alloc_frac
=
allocation
/
(
double
)
used
;
// The result can be larger than 1.0 due to direct to old allocations.
// These allocations should ideally not be counted but since it is not possible
// to filter them out here we just cap the fraction to be at most 1.0.
double
alloc_frac
=
MIN2
(
1.0
,
(
double
)
allocated_since_last_gc
/
used
);
_allocation_fraction
.
sample
(
alloc_frac
);
}
global_stats
()
->
update_allocating_threads
();
...
...
@@ -126,33 +131,32 @@ void ThreadLocalAllocBuffer::make_parsable(bool retire) {
}
void
ThreadLocalAllocBuffer
::
resize_all_tlabs
()
{
for
(
JavaThread
*
thread
=
Threads
::
first
();
thread
;
thread
=
thread
->
next
())
{
thread
->
tlab
().
resize
();
if
(
ResizeTLAB
)
{
for
(
JavaThread
*
thread
=
Threads
::
first
();
thread
!=
NULL
;
thread
=
thread
->
next
())
{
thread
->
tlab
().
resize
();
}
}
}
void
ThreadLocalAllocBuffer
::
resize
()
{
// Compute the next tlab size using expected allocation amount
assert
(
ResizeTLAB
,
"Should not call this otherwise"
);
size_t
alloc
=
(
size_t
)(
_allocation_fraction
.
average
()
*
(
Universe
::
heap
()
->
tlab_capacity
(
myThread
())
/
HeapWordSize
));
size_t
new_size
=
alloc
/
_target_refills
;
if
(
ResizeTLAB
)
{
// Compute the next tlab size using expected allocation amount
size_t
alloc
=
(
size_t
)(
_allocation_fraction
.
average
()
*
(
Universe
::
heap
()
->
tlab_capacity
(
myThread
())
/
HeapWordSize
));
size_t
new_size
=
alloc
/
_target_refills
;
new_size
=
MIN2
(
MAX2
(
new_size
,
min_size
()),
max_size
());
new_size
=
MIN2
(
MAX2
(
new_size
,
min_size
()),
max_size
());
size_t
aligned_new_size
=
align_object_size
(
new_size
);
size_t
aligned_new_size
=
align_object_size
(
new_size
);
if
(
PrintTLAB
&&
Verbose
)
{
gclog_or_tty
->
print
(
"TLAB new size: thread: "
INTPTR_FORMAT
" [id: %2d]"
" refills %d alloc: %8.6f desired_size: "
SIZE_FORMAT
" -> "
SIZE_FORMAT
"
\n
"
,
myThread
(),
myThread
()
->
osthread
()
->
thread_id
(),
_target_refills
,
_allocation_fraction
.
average
(),
desired_size
(),
aligned_new_size
);
}
set_desired_size
(
aligned_new_size
);
set_refill_waste_limit
(
initial_refill_waste_limit
());
if
(
PrintTLAB
&&
Verbose
)
{
gclog_or_tty
->
print
(
"TLAB new size: thread: "
INTPTR_FORMAT
" [id: %2d]"
" refills %d alloc: %8.6f desired_size: "
SIZE_FORMAT
" -> "
SIZE_FORMAT
"
\n
"
,
myThread
(),
myThread
()
->
osthread
()
->
thread_id
(),
_target_refills
,
_allocation_fraction
.
average
(),
desired_size
(),
aligned_new_size
);
}
set_desired_size
(
aligned_new_size
);
set_refill_waste_limit
(
initial_refill_waste_limit
());
}
void
ThreadLocalAllocBuffer
::
initialize_statistics
()
{
...
...
@@ -248,31 +252,13 @@ size_t ThreadLocalAllocBuffer::initial_desired_size() {
return
init_sz
;
}
const
size_t
ThreadLocalAllocBuffer
::
max_size
()
{
// TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE].
// This restriction could be removed by enabling filling with multiple arrays.
// If we compute that the reasonable way as
// header_size + ((sizeof(jint) * max_jint) / HeapWordSize)
// we'll overflow on the multiply, so we do the divide first.
// We actually lose a little by dividing first,
// but that just makes the TLAB somewhat smaller than the biggest array,
// which is fine, since we'll be able to fill that.
size_t
unaligned_max_size
=
typeArrayOopDesc
::
header_size
(
T_INT
)
+
sizeof
(
jint
)
*
((
juint
)
max_jint
/
(
size_t
)
HeapWordSize
);
return
align_size_down
(
unaligned_max_size
,
MinObjAlignment
);
}
void
ThreadLocalAllocBuffer
::
print_stats
(
const
char
*
tag
)
{
Thread
*
thrd
=
myThread
();
size_t
waste
=
_gc_waste
+
_slow_refill_waste
+
_fast_refill_waste
;
size_t
alloc
=
_number_of_refills
*
_desired_size
;
double
waste_percent
=
alloc
==
0
?
0.0
:
100.0
*
waste
/
alloc
;
size_t
tlab_used
=
Universe
::
heap
()
->
tlab_capacity
(
thrd
)
-
Universe
::
heap
()
->
unsafe_max_tlab_alloc
(
thrd
);
size_t
tlab_used
=
Universe
::
heap
()
->
tlab_used
(
thrd
);
gclog_or_tty
->
print
(
"TLAB: %s thread: "
INTPTR_FORMAT
" [id: %2d]"
" desired_size: "
SIZE_FORMAT
"KB"
" slow allocs: %d refill waste: "
SIZE_FORMAT
"B"
...
...
hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
浏览文件 @
b888cc0d
...
...
@@ -45,7 +45,9 @@ private:
HeapWord
*
_end
;
// allocation end (excluding alignment_reserve)
size_t
_desired_size
;
// desired size (including alignment_reserve)
size_t
_refill_waste_limit
;
// hold onto tlab if free() is larger than this
size_t
_allocated_before_last_gc
;
// total bytes allocated up until the last gc
static
size_t
_max_size
;
// maximum size of any TLAB
static
unsigned
_target_refills
;
// expected number of refills between GCs
unsigned
_number_of_refills
;
...
...
@@ -99,12 +101,13 @@ private:
static
GlobalTLABStats
*
global_stats
()
{
return
_global_stats
;
}
public:
ThreadLocalAllocBuffer
()
:
_allocation_fraction
(
TLABAllocationWeight
)
{
ThreadLocalAllocBuffer
()
:
_allocation_fraction
(
TLABAllocationWeight
)
,
_allocated_before_last_gc
(
0
)
{
// do nothing. tlabs must be inited by initialize() calls
}
static
const
size_t
min_size
()
{
return
align_object_size
(
MinTLABSize
/
HeapWordSize
);
}
static
const
size_t
max_size
();
static
const
size_t
max_size
()
{
assert
(
_max_size
!=
0
,
"max_size not set up"
);
return
_max_size
;
}
static
void
set_max_size
(
size_t
max_size
)
{
_max_size
=
max_size
;
}
HeapWord
*
start
()
const
{
return
_start
;
}
HeapWord
*
end
()
const
{
return
_end
;
}
...
...
hotspot/src/share/vm/memory/universe.cpp
浏览文件 @
b888cc0d
...
...
@@ -816,6 +816,8 @@ jint Universe::initialize_heap() {
Universe
::
_collectedHeap
=
new
GenCollectedHeap
(
gc_policy
);
}
ThreadLocalAllocBuffer
::
set_max_size
(
Universe
::
heap
()
->
max_tlab_size
());
jint
status
=
Universe
::
heap
()
->
initialize
();
if
(
status
!=
JNI_OK
)
{
return
status
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录