Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
75eb81af
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
75eb81af
编写于
8月 09, 2010
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6970376: ParNew: shared TaskQueue statistics
Reviewed-by: ysr
上级
e6ad5bbe
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
127 addition
and
95 deletion
+127
-95
src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
+105
-66
src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
+22
-29
未找到文件。
src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
浏览文件 @
75eb81af
...
...
@@ -51,9 +51,14 @@ ParScanThreadState::ParScanThreadState(Space* to_space_,
_is_alive_closure
(
gen_
),
_scan_weak_ref_closure
(
gen_
,
this
),
_keep_alive_closure
(
&
_scan_weak_ref_closure
),
_promotion_failure_size
(
0
),
_pushes
(
0
),
_pops
(
0
),
_steals
(
0
),
_steal_attempts
(
0
),
_term_attempts
(
0
),
_strong_roots_time
(
0.0
),
_term_time
(
0.0
)
{
#if TASKQUEUE_STATS
_term_attempts
=
0
;
_overflow_refills
=
0
;
_overflow_refill_objs
=
0
;
#endif // TASKQUEUE_STATS
_survivor_chunk_array
=
(
ChunkArray
*
)
old_gen
()
->
get_data_recorder
(
thread_num
());
_hash_seed
=
17
;
// Might want to take time-based random value.
...
...
@@ -100,7 +105,6 @@ void ParScanThreadState::scan_partial_array_and_push_remainder(oop old) {
// Push remainder.
bool
ok
=
work_queue
()
->
push
(
old
);
assert
(
ok
,
"just popped, push must be okay"
);
note_push
();
}
else
{
// Restore length so that it can be used if there
// is a promotion failure and forwarding pointers
...
...
@@ -126,7 +130,6 @@ void ParScanThreadState::trim_queues(int max_size) {
while
(
queue
->
size
()
>
(
juint
)
max_size
)
{
oop
obj_to_scan
;
if
(
queue
->
pop_local
(
obj_to_scan
))
{
note_pop
();
if
((
HeapWord
*
)
obj_to_scan
<
young_old_boundary
())
{
if
(
obj_to_scan
->
is_objArray
()
&&
obj_to_scan
->
is_forwarded
()
&&
...
...
@@ -271,20 +274,28 @@ public:
GrowableArray
<
oop
>**
overflow_stacks_
,
size_t
desired_plab_sz
,
ParallelTaskTerminator
&
term
);
~
ParScanThreadStateSet
()
{
TASKQUEUE_STATS_ONLY
(
reset_stats
());
}
inline
ParScanThreadState
&
thread_state
(
int
i
);
int
pushes
()
{
return
_pushes
;
}
int
pops
()
{
return
_pops
;
}
int
steals
()
{
return
_steals
;
}
void
reset
(
bool
promotion_failed
);
void
flush
();
#if TASKQUEUE_STATS
static
void
print_termination_stats_hdr
(
outputStream
*
const
st
=
gclog_or_tty
);
void
print_termination_stats
(
outputStream
*
const
st
=
gclog_or_tty
);
static
void
print_taskqueue_stats_hdr
(
outputStream
*
const
st
=
gclog_or_tty
);
void
print_taskqueue_stats
(
outputStream
*
const
st
=
gclog_or_tty
);
void
reset_stats
();
#endif // TASKQUEUE_STATS
private:
ParallelTaskTerminator
&
_term
;
ParNewGeneration
&
_gen
;
Generation
&
_next_gen
;
// staticstics
int
_pushes
;
int
_pops
;
int
_steals
;
};
...
...
@@ -294,8 +305,7 @@ ParScanThreadStateSet::ParScanThreadStateSet(
GrowableArray
<
oop
>**
overflow_stack_set_
,
size_t
desired_plab_sz
,
ParallelTaskTerminator
&
term
)
:
ResourceArray
(
sizeof
(
ParScanThreadState
),
num_threads
),
_gen
(
gen
),
_next_gen
(
old_gen
),
_term
(
term
),
_pushes
(
0
),
_pops
(
0
),
_steals
(
0
)
_gen
(
gen
),
_next_gen
(
old_gen
),
_term
(
term
)
{
assert
(
num_threads
>
0
,
"sanity check!"
);
// Initialize states.
...
...
@@ -323,6 +333,82 @@ void ParScanThreadStateSet::reset(bool promotion_failed)
}
}
#if TASKQUEUE_STATS
void
ParScanThreadState
::
reset_stats
()
{
taskqueue_stats
().
reset
();
_term_attempts
=
0
;
_overflow_refills
=
0
;
_overflow_refill_objs
=
0
;
}
void
ParScanThreadStateSet
::
reset_stats
()
{
for
(
int
i
=
0
;
i
<
length
();
++
i
)
{
thread_state
(
i
).
reset_stats
();
}
}
void
ParScanThreadStateSet
::
print_termination_stats_hdr
(
outputStream
*
const
st
)
{
st
->
print_raw_cr
(
"GC Termination Stats"
);
st
->
print_raw_cr
(
" elapsed --strong roots-- "
"-------termination-------"
);
st
->
print_raw_cr
(
"thr ms ms % "
" ms % attempts"
);
st
->
print_raw_cr
(
"--- --------- --------- ------ "
"--------- ------ --------"
);
}
void
ParScanThreadStateSet
::
print_termination_stats
(
outputStream
*
const
st
)
{
print_termination_stats_hdr
(
st
);
for
(
int
i
=
0
;
i
<
length
();
++
i
)
{
const
ParScanThreadState
&
pss
=
thread_state
(
i
);
const
double
elapsed_ms
=
pss
.
elapsed_time
()
*
1000.0
;
const
double
s_roots_ms
=
pss
.
strong_roots_time
()
*
1000.0
;
const
double
term_ms
=
pss
.
term_time
()
*
1000.0
;
st
->
print_cr
(
"%3d %9.2f %9.2f %6.2f "
"%9.2f %6.2f "
SIZE_FORMAT_W
(
8
),
i
,
elapsed_ms
,
s_roots_ms
,
s_roots_ms
*
100
/
elapsed_ms
,
term_ms
,
term_ms
*
100
/
elapsed_ms
,
pss
.
term_attempts
());
}
}
// Print stats related to work queue activity.
void
ParScanThreadStateSet
::
print_taskqueue_stats_hdr
(
outputStream
*
const
st
)
{
st
->
print_raw_cr
(
"GC Task Stats"
);
st
->
print_raw
(
"thr "
);
TaskQueueStats
::
print_header
(
1
,
st
);
st
->
cr
();
st
->
print_raw
(
"--- "
);
TaskQueueStats
::
print_header
(
2
,
st
);
st
->
cr
();
}
void
ParScanThreadStateSet
::
print_taskqueue_stats
(
outputStream
*
const
st
)
{
print_taskqueue_stats_hdr
(
st
);
TaskQueueStats
totals
;
for
(
int
i
=
0
;
i
<
length
();
++
i
)
{
const
ParScanThreadState
&
pss
=
thread_state
(
i
);
const
TaskQueueStats
&
stats
=
pss
.
taskqueue_stats
();
st
->
print
(
"%3d "
,
i
);
stats
.
print
(
st
);
st
->
cr
();
totals
+=
stats
;
if
(
pss
.
overflow_refills
()
>
0
)
{
st
->
print_cr
(
" "
SIZE_FORMAT_W
(
10
)
" overflow refills "
SIZE_FORMAT_W
(
10
)
" overflow objects"
,
pss
.
overflow_refills
(),
pss
.
overflow_refill_objs
());
}
}
st
->
print
(
"tot "
);
totals
.
print
(
st
);
st
->
cr
();
DEBUG_ONLY
(
totals
.
verify
());
}
#endif // TASKQUEUE_STATS
void
ParScanThreadStateSet
::
flush
()
{
// Work in this loop should be kept as lightweight as
...
...
@@ -346,42 +432,8 @@ void ParScanThreadStateSet::flush()
// Inform old gen that we're done.
_next_gen
.
par_promote_alloc_done
(
i
);
_next_gen
.
par_oop_since_save_marks_iterate_done
(
i
);
// Flush stats related to work queue activity (push/pop/steal)
// This could conceivably become a bottleneck; if so, we'll put the
// stat's gathering under the flag.
if
(
PAR_STATS_ENABLED
)
{
_pushes
+=
par_scan_state
.
pushes
();
_pops
+=
par_scan_state
.
pops
();
_steals
+=
par_scan_state
.
steals
();
if
(
ParallelGCVerbose
)
{
gclog_or_tty
->
print
(
"Thread %d complete:
\n
"
" Pushes: %7d Pops: %7d Steals %7d (in %d attempts)
\n
"
,
i
,
par_scan_state
.
pushes
(),
par_scan_state
.
pops
(),
par_scan_state
.
steals
(),
par_scan_state
.
steal_attempts
());
if
(
par_scan_state
.
overflow_pushes
()
>
0
||
par_scan_state
.
overflow_refills
()
>
0
)
{
gclog_or_tty
->
print
(
" Overflow pushes: %7d "
"Overflow refills: %7d for %d objs.
\n
"
,
par_scan_state
.
overflow_pushes
(),
par_scan_state
.
overflow_refills
(),
par_scan_state
.
overflow_refill_objs
());
}
double
elapsed
=
par_scan_state
.
elapsed
();
double
strong_roots
=
par_scan_state
.
strong_roots_time
();
double
term
=
par_scan_state
.
term_time
();
gclog_or_tty
->
print
(
" Elapsed: %7.2f ms.
\n
"
" Strong roots: %7.2f ms (%6.2f%%)
\n
"
" Termination: %7.2f ms (%6.2f%%) (in %d entries)
\n
"
,
elapsed
*
1000.0
,
strong_roots
*
1000.0
,
(
strong_roots
*
100.0
/
elapsed
),
term
*
1000.0
,
(
term
*
100.0
/
elapsed
),
par_scan_state
.
term_attempts
());
}
}
}
if
(
UseConcMarkSweepGC
&&
ParallelGCThreads
>
0
)
{
// We need to call this even when ResizeOldPLAB is disabled
// so as to avoid breaking some asserts. While we may be able
...
...
@@ -456,15 +508,12 @@ void ParEvacuateFollowersClosure::do_void() {
// We have no local work, attempt to steal from other threads.
// attempt to steal work from promoted.
par_scan_state
()
->
note_steal_attempt
();
if
(
task_queues
()
->
steal
(
par_scan_state
()
->
thread_num
(),
par_scan_state
()
->
hash_seed
(),
obj_to_scan
))
{
par_scan_state
()
->
note_steal
();
bool
res
=
work_q
->
push
(
obj_to_scan
);
assert
(
res
,
"Empty queue should have room for a push."
);
par_scan_state
()
->
note_push
();
// if successful, goto Start.
continue
;
...
...
@@ -842,17 +891,6 @@ void ParNewGeneration::collect(bool full,
}
thread_state_set
.
reset
(
promotion_failed
());
if
(
PAR_STATS_ENABLED
&&
ParallelGCVerbose
)
{
gclog_or_tty
->
print
(
"Thread totals:
\n
"
" Pushes: %7d Pops: %7d Steals %7d (sum = %7d).
\n
"
,
thread_state_set
.
pushes
(),
thread_state_set
.
pops
(),
thread_state_set
.
steals
(),
thread_state_set
.
pops
()
+
thread_state_set
.
steals
());
}
assert
(
thread_state_set
.
pushes
()
==
thread_state_set
.
pops
()
+
thread_state_set
.
steals
(),
"Or else the queues are leaky."
);
// Process (weak) reference objects found during scavenge.
ReferenceProcessor
*
rp
=
ref_processor
();
IsAliveClosure
is_alive
(
this
);
...
...
@@ -932,6 +970,9 @@ void ParNewGeneration::collect(bool full,
gch
->
print_heap_change
(
gch_prev_used
);
}
TASKQUEUE_STATS_ONLY
(
thread_state_set
.
print_termination_stats
());
TASKQUEUE_STATS_ONLY
(
thread_state_set
.
print_taskqueue_stats
());
if
(
UseAdaptiveSizePolicy
)
{
size_policy
->
minor_collection_end
(
gch
->
gc_cause
());
size_policy
->
avg_survived
()
->
sample
(
from
()
->
used
());
...
...
@@ -1104,9 +1145,8 @@ oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
gclog_or_tty
->
print
(
"queue overflow!
\n
"
);
}
push_on_overflow_list
(
old
,
par_scan_state
);
par_scan_state
->
note_overflow_push
(
);
TASKQUEUE_STATS_ONLY
(
par_scan_state
->
taskqueue_stats
().
record_overflow
(
0
)
);
}
par_scan_state
->
note_push
();
return
new_obj
;
}
...
...
@@ -1227,9 +1267,8 @@ oop ParNewGeneration::copy_to_survivor_space_with_undo(
if
(
simulate_overflow
||
!
par_scan_state
->
work_queue
()
->
push
(
obj_to_push
))
{
// Add stats for overflow pushes.
push_on_overflow_list
(
old
,
par_scan_state
);
par_scan_state
->
note_overflow_push
(
);
TASKQUEUE_STATS_ONLY
(
par_scan_state
->
taskqueue_stats
().
record_overflow
(
0
)
);
}
par_scan_state
->
note_push
();
return
new_obj
;
}
...
...
@@ -1466,7 +1505,7 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan
cur
=
next
;
n
++
;
}
par_scan_state
->
note_overflow_refill
(
n
);
TASKQUEUE_STATS_ONLY
(
par_scan_state
->
note_overflow_refill
(
n
)
);
#ifndef PRODUCT
assert
(
_num_par_pushes
>=
n
,
"Too many pops?"
);
Atomic
::
add_ptr
(
-
(
intptr_t
)
n
,
&
_num_par_pushes
);
...
...
src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
浏览文件 @
75eb81af
...
...
@@ -36,9 +36,6 @@ class ParEvacuateFollowersClosure;
typedef
Padded
<
OopTaskQueue
>
ObjToScanQueue
;
typedef
GenericTaskQueueSet
<
ObjToScanQueue
>
ObjToScanQueueSet
;
// Enable this to get push/pop/steal stats.
const
int
PAR_STATS_ENABLED
=
0
;
class
ParKeepAliveClosure
:
public
DefNewGeneration
::
KeepAliveClosure
{
private:
ParScanWeakRefClosure
*
_par_cl
;
...
...
@@ -94,8 +91,11 @@ class ParScanThreadState {
bool
_to_space_full
;
int
_pushes
,
_pops
,
_steals
,
_steal_attempts
,
_term_attempts
;
int
_overflow_pushes
,
_overflow_refills
,
_overflow_refill_objs
;
#if TASKQUEUE_STATS
size_t
_term_attempts
;
size_t
_overflow_refills
;
size_t
_overflow_refill_objs
;
#endif // TASKQUEUE_STATS
// Stats for promotion failure
size_t
_promotion_failure_size
;
...
...
@@ -181,45 +181,38 @@ class ParScanThreadState {
}
void
print_and_clear_promotion_failure_size
();
int
pushes
()
{
return
_pushes
;
}
int
pops
()
{
return
_pops
;
}
int
steals
()
{
return
_steals
;
}
int
steal_attempts
()
{
return
_steal_attempts
;
}
int
term_attempts
()
{
return
_term_attempts
;
}
int
overflow_pushes
()
{
return
_overflow_pushes
;
}
int
overflow_refills
()
{
return
_overflow_refills
;
}
int
overflow_refill_objs
()
{
return
_overflow_refill_objs
;
}
void
note_push
()
{
if
(
PAR_STATS_ENABLED
)
_pushes
++
;
}
void
note_pop
()
{
if
(
PAR_STATS_ENABLED
)
_pops
++
;
}
void
note_steal
()
{
if
(
PAR_STATS_ENABLED
)
_steals
++
;
}
void
note_steal_attempt
()
{
if
(
PAR_STATS_ENABLED
)
_steal_attempts
++
;
}
void
note_term_attempt
()
{
if
(
PAR_STATS_ENABLED
)
_term_attempts
++
;
}
void
note_overflow_push
()
{
if
(
PAR_STATS_ENABLED
)
_overflow_pushes
++
;
}
void
note_overflow_refill
(
int
objs
)
{
if
(
PAR_STATS_ENABLED
)
{
_overflow_refills
++
;
_overflow_refill_objs
+=
objs
;
}
#if TASKQUEUE_STATS
TaskQueueStats
&
taskqueue_stats
()
const
{
return
_work_queue
->
stats
;
}
size_t
term_attempts
()
const
{
return
_term_attempts
;
}
size_t
overflow_refills
()
const
{
return
_overflow_refills
;
}
size_t
overflow_refill_objs
()
const
{
return
_overflow_refill_objs
;
}
void
note_term_attempt
()
{
++
_term_attempts
;
}
void
note_overflow_refill
(
size_t
objs
)
{
++
_overflow_refills
;
_overflow_refill_objs
+=
objs
;
}
void
reset_stats
();
#endif // TASKQUEUE_STATS
void
start_strong_roots
()
{
_start_strong_roots
=
os
::
elapsedTime
();
}
void
end_strong_roots
()
{
_strong_roots_time
+=
(
os
::
elapsedTime
()
-
_start_strong_roots
);
}
double
strong_roots_time
()
{
return
_strong_roots_time
;
}
double
strong_roots_time
()
const
{
return
_strong_roots_time
;
}
void
start_term_time
()
{
note_term_attempt
(
);
TASKQUEUE_STATS_ONLY
(
note_term_attempt
()
);
_start_term
=
os
::
elapsedTime
();
}
void
end_term_time
()
{
_term_time
+=
(
os
::
elapsedTime
()
-
_start_term
);
}
double
term_time
()
{
return
_term_time
;
}
double
term_time
()
const
{
return
_term_time
;
}
double
elapsed
()
{
double
elapsed
_time
()
const
{
return
os
::
elapsedTime
()
-
_start
;
}
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录