Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
f09ff5c1
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,发现更多精彩内容 >>
提交
f09ff5c1
编写于
2月 02, 2013
作者:
C
ctornqvi
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
ac548931
384b2f80
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
171 addition
and
14 deletion
+171
-14
hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
+5
-0
hotspot/src/share/vm/memory/allocation.hpp
hotspot/src/share/vm/memory/allocation.hpp
+3
-2
hotspot/src/share/vm/prims/whitebox.cpp
hotspot/src/share/vm/prims/whitebox.cpp
+63
-0
hotspot/src/share/vm/services/memBaseline.cpp
hotspot/src/share/vm/services/memBaseline.cpp
+1
-0
hotspot/src/share/vm/services/memPtr.cpp
hotspot/src/share/vm/services/memPtr.cpp
+1
-1
hotspot/src/share/vm/services/memPtr.hpp
hotspot/src/share/vm/services/memPtr.hpp
+5
-5
hotspot/src/share/vm/services/memRecorder.cpp
hotspot/src/share/vm/services/memRecorder.cpp
+3
-2
hotspot/src/share/vm/services/memRecorder.hpp
hotspot/src/share/vm/services/memRecorder.hpp
+4
-2
hotspot/src/share/vm/services/memTrackWorker.cpp
hotspot/src/share/vm/services/memTrackWorker.cpp
+11
-0
hotspot/src/share/vm/services/memTrackWorker.hpp
hotspot/src/share/vm/services/memTrackWorker.hpp
+1
-0
hotspot/src/share/vm/services/memTracker.cpp
hotspot/src/share/vm/services/memTracker.cpp
+49
-1
hotspot/src/share/vm/services/memTracker.hpp
hotspot/src/share/vm/services/memTracker.hpp
+25
-1
未找到文件。
hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
浏览文件 @
f09ff5c1
...
...
@@ -76,4 +76,9 @@ public class WhiteBox {
public
native
long
g1NumFreeRegions
();
public
native
int
g1RegionSize
();
public
native
Object
[]
parseCommandLine
(
String
commandline
,
DiagnosticCommand
[]
args
);
// NMT
public
native
boolean
NMTAllocTest
();
public
native
boolean
NMTFreeTestMemory
();
public
native
boolean
NMTWaitForDataMerge
();
}
hotspot/src/share/vm/memory/allocation.hpp
浏览文件 @
f09ff5c1
...
...
@@ -145,9 +145,10 @@ enum MemoryType {
mtChunk
=
0x0B00
,
// chunk that holds content of arenas
mtJavaHeap
=
0x0C00
,
// Java heap
mtClassShared
=
0x0D00
,
// class data sharing
mt_number_of_types
=
0x000D
,
// number of memory types (mtDontTrack
mtTest
=
0x0E00
,
// Test type for verifying NMT
mt_number_of_types
=
0x000E
,
// number of memory types (mtDontTrack
// is not included as validate type)
mtDontTrack
=
0x0
E
00
,
// memory we do not or cannot track
mtDontTrack
=
0x0
F
00
,
// memory we do not or cannot track
mt_masks
=
0x7F00
,
// object type mask
...
...
hotspot/src/share/vm/prims/whitebox.cpp
浏览文件 @
f09ff5c1
...
...
@@ -43,6 +43,10 @@
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#endif // !SERIALGC
#ifdef INCLUDE_NMT
#include "services/memTracker.hpp"
#endif // INCLUDE_NMT
bool
WhiteBox
::
_used
=
false
;
WB_ENTRY
(
jlong
,
WB_GetObjectAddress
(
JNIEnv
*
env
,
jobject
o
,
jobject
obj
))
...
...
@@ -110,6 +114,60 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
WB_END
#endif // !SERIALGC
#ifdef INCLUDE_NMT
// Keep track of the 3 allocations in NMTAllocTest so we can free them later
// on and verify that they're not visible anymore
static
void
*
nmtMtTest1
=
NULL
,
*
nmtMtTest2
=
NULL
,
*
nmtMtTest3
=
NULL
;
// Alloc memory using the test memory type so that we can use that to see if
// NMT picks it up correctly
WB_ENTRY
(
jboolean
,
WB_NMTAllocTest
(
JNIEnv
*
env
))
void
*
mem
;
if
(
!
MemTracker
::
is_on
()
||
MemTracker
::
shutdown_in_progress
())
{
return
false
;
}
// Allocate 2 * 128k + 256k + 1024k and free the 1024k one to make sure we track
// everything correctly. Total should be 512k held alive.
nmtMtTest1
=
os
::
malloc
(
128
*
1024
,
mtTest
);
mem
=
os
::
malloc
(
1024
*
1024
,
mtTest
);
nmtMtTest2
=
os
::
malloc
(
256
*
1024
,
mtTest
);
os
::
free
(
mem
,
mtTest
);
nmtMtTest3
=
os
::
malloc
(
128
*
1024
,
mtTest
);
return
true
;
WB_END
// Free the memory allocated by NMTAllocTest
WB_ENTRY
(
jboolean
,
WB_NMTFreeTestMemory
(
JNIEnv
*
env
))
if
(
nmtMtTest1
==
NULL
||
nmtMtTest2
==
NULL
||
nmtMtTest3
==
NULL
)
{
return
false
;
}
os
::
free
(
nmtMtTest1
,
mtTest
);
nmtMtTest1
=
NULL
;
os
::
free
(
nmtMtTest2
,
mtTest
);
nmtMtTest2
=
NULL
;
os
::
free
(
nmtMtTest3
,
mtTest
);
nmtMtTest3
=
NULL
;
return
true
;
WB_END
// Block until the current generation of NMT data to be merged, used to reliably test the NMT feature
WB_ENTRY
(
jboolean
,
WB_NMTWaitForDataMerge
(
JNIEnv
*
env
))
if
(
!
MemTracker
::
is_on
()
||
MemTracker
::
shutdown_in_progress
())
{
return
false
;
}
return
MemTracker
::
wbtest_wait_for_data_merge
();
WB_END
#endif // INCLUDE_NMT
//Some convenience methods to deal with objects from java
int
WhiteBox
::
offset_for_field
(
const
char
*
field_name
,
oop
object
,
Symbol
*
signature_symbol
)
{
...
...
@@ -177,6 +235,11 @@ static JNINativeMethod methods[] = {
{
CC
"g1NumFreeRegions"
,
CC
"()J"
,
(
void
*
)
&
WB_G1NumFreeRegions
},
{
CC
"g1RegionSize"
,
CC
"()I"
,
(
void
*
)
&
WB_G1RegionSize
},
#endif // !SERIALGC
#ifdef INCLUDE_NMT
{
CC
"NMTAllocTest"
,
CC
"()Z"
,
(
void
*
)
&
WB_NMTAllocTest
},
{
CC
"NMTFreeTestMemory"
,
CC
"()Z"
,
(
void
*
)
&
WB_NMTFreeTestMemory
},
{
CC
"NMTWaitForDataMerge"
,
CC
"()Z"
,
(
void
*
)
&
WB_NMTWaitForDataMerge
},
#endif // INCLUDE_NMT
};
#undef CC
...
...
hotspot/src/share/vm/services/memBaseline.cpp
浏览文件 @
f09ff5c1
...
...
@@ -40,6 +40,7 @@ MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
{
mtNMT
,
"Memory Tracking"
},
{
mtChunk
,
"Pooled Free Chunks"
},
{
mtClassShared
,
"Shared spaces for classes"
},
{
mtTest
,
"Test"
},
{
mtNone
,
"Unknown"
}
// It can happen when type tagging records are lagging
// behind
};
...
...
hotspot/src/share/vm/services/memPtr.cpp
浏览文件 @
f09ff5c1
...
...
@@ -27,8 +27,8 @@
#include "services/memTracker.hpp"
volatile
jint
SequenceGenerator
::
_seq_number
=
1
;
volatile
unsigned
long
SequenceGenerator
::
_generation
=
1
;
NOT_PRODUCT
(
jint
SequenceGenerator
::
_max_seq_number
=
1
;)
DEBUG_ONLY
(
volatile
unsigned
long
SequenceGenerator
::
_generation
=
0
;)
jint
SequenceGenerator
::
next
()
{
jint
seq
=
Atomic
::
add
(
1
,
&
_seq_number
);
...
...
hotspot/src/share/vm/services/memPtr.hpp
浏览文件 @
f09ff5c1
...
...
@@ -47,16 +47,16 @@ class SequenceGenerator : AllStatic {
static
void
reset
()
{
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"Safepoint required"
);
_seq_number
=
1
;
DEBUG_ONLY
(
_generation
++
;)
_generation
++
;
};
DEBUG_ONLY
(
static
unsigned
long
current_generation
()
{
return
(
unsigned
long
)
_generation
;
})
static
unsigned
long
current_generation
()
{
return
_generation
;
}
NOT_PRODUCT
(
static
jint
max_seq_num
()
{
return
_max_seq_number
;
})
private:
static
volatile
jint
_seq_number
;
NOT_PRODUCT
(
static
jint
_max_seq_number
;
)
DEBUG_ONLY
(
static
volatile
unsigned
long
_generation
;
)
static
volatile
jint
_seq_number
;
static
volatile
unsigned
long
_generation
;
NOT_PRODUCT
(
static
jint
_max_seq_number
;
)
};
/*
...
...
hotspot/src/share/vm/services/memRecorder.cpp
浏览文件 @
f09ff5c1
...
...
@@ -55,7 +55,7 @@ volatile jint MemRecorder::_instance_count = 0;
MemRecorder
::
MemRecorder
()
{
assert
(
MemTracker
::
is_on
(),
"Native memory tracking is off"
);
Atomic
::
inc
(
&
_instance_count
);
debug_only
(
set_generation
();)
set_generation
();
if
(
MemTracker
::
track_callsite
())
{
_pointer_records
=
new
(
std
::
nothrow
)
FixedSizeMemPointerArray
<
SeqMemPointerRecordEx
,
...
...
@@ -151,11 +151,12 @@ SequencedRecordIterator MemRecorder::pointer_itr() {
}
#ifdef ASSERT
void
MemRecorder
::
set_generation
()
{
_generation
=
SequenceGenerator
::
current_generation
();
}
#ifdef ASSERT
void
MemRecorder
::
check_dup_seq
(
jint
seq
)
const
{
MemPointerArrayIteratorImpl
itr
(
_pointer_records
);
MemPointerRecord
*
rc
=
(
MemPointerRecord
*
)
itr
.
current
();
...
...
hotspot/src/share/vm/services/memRecorder.hpp
浏览文件 @
f09ff5c1
...
...
@@ -213,7 +213,7 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
// used for linked list
MemRecorder
*
_next
;
// active recorder can only record a certain generation data
debug_only
(
unsigned
long
_generation
;)
unsigned
long
_generation
;
protected:
_NOINLINE_
MemRecorder
();
...
...
@@ -251,6 +251,8 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
SequencedRecordIterator
pointer_itr
();
// return the generation of this recorder which it belongs to
unsigned
long
get_generation
()
const
{
return
_generation
;
}
protected:
// number of MemRecorder instance
static
volatile
jint
_instance_count
;
...
...
@@ -263,7 +265,7 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
static
int
sort_record_fn
(
const
void
*
e1
,
const
void
*
e2
);
debug_only
(
void
check_dup_seq
(
jint
seq
)
const
;)
debug_only
(
void
set_generation
();)
void
set_generation
();
};
#endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP
hotspot/src/share/vm/services/memTrackWorker.cpp
浏览文件 @
f09ff5c1
...
...
@@ -91,6 +91,8 @@ void MemTrackWorker::run() {
MemSnapshot
*
snapshot
=
MemTracker
::
get_snapshot
();
assert
(
snapshot
!=
NULL
,
"Worker should not be started"
);
MemRecorder
*
rec
;
unsigned
long
processing_generation
=
0
;
bool
worker_idle
=
false
;
while
(
!
MemTracker
::
shutdown_in_progress
())
{
NOT_PRODUCT
(
_last_gen_in_use
=
generations_in_use
();)
...
...
@@ -100,6 +102,12 @@ void MemTrackWorker::run() {
rec
=
_gen
[
_head
].
next_recorder
();
}
if
(
rec
!=
NULL
)
{
if
(
rec
->
get_generation
()
!=
processing_generation
||
worker_idle
)
{
processing_generation
=
rec
->
get_generation
();
worker_idle
=
false
;
MemTracker
::
set_current_processing_generation
(
processing_generation
);
}
// merge the recorder into staging area
if
(
!
snapshot
->
merge
(
rec
))
{
MemTracker
::
shutdown
(
MemTracker
::
NMT_out_of_memory
);
...
...
@@ -129,6 +137,9 @@ void MemTrackWorker::run() {
MemTracker
::
shutdown
(
MemTracker
::
NMT_out_of_memory
);
}
}
else
{
// worker thread is idle
worker_idle
=
true
;
MemTracker
::
report_worker_idle
();
snapshot
->
wait
(
1000
);
ThreadCritical
tc
;
// check if more data arrived
...
...
hotspot/src/share/vm/services/memTrackWorker.hpp
浏览文件 @
f09ff5c1
...
...
@@ -107,6 +107,7 @@ class MemTrackWorker : public NamedThread {
NOT_PRODUCT
(
int
_merge_count
;)
NOT_PRODUCT
(
int
_last_gen_in_use
;)
// how many generations are queued
inline
int
generations_in_use
()
const
{
return
(
_tail
>=
_head
?
(
_tail
-
_head
+
1
)
:
(
MAX_GENERATIONS
-
(
_head
-
_tail
)
+
1
));
}
...
...
hotspot/src/share/vm/services/memTracker.cpp
浏览文件 @
f09ff5c1
...
...
@@ -29,6 +29,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/vm_operations.hpp"
#include "services/memPtr.hpp"
#include "services/memReporter.hpp"
#include "services/memTracker.hpp"
...
...
@@ -65,6 +66,8 @@ volatile MemTracker::NMTStates MemTracker::_state = NMT_uninited;
MemTracker
::
ShutdownReason
MemTracker
::
_reason
=
NMT_shutdown_none
;
int
MemTracker
::
_thread_count
=
255
;
volatile
jint
MemTracker
::
_pooled_recorder_count
=
0
;
volatile
unsigned
long
MemTracker
::
_processing_generation
=
0
;
volatile
bool
MemTracker
::
_worker_thread_idle
=
false
;
debug_only
(
intx
MemTracker
::
_main_thread_tid
=
0
;)
NOT_PRODUCT
(
volatile
jint
MemTracker
::
_pending_recorder_count
=
0
;)
...
...
@@ -279,7 +282,7 @@ MemRecorder* MemTracker::get_new_or_pooled_instance() {
}
cur_head
->
set_next
(
NULL
);
Atomic
::
dec
(
&
_pooled_recorder_count
);
debug_only
(
cur_head
->
set_generation
();)
cur_head
->
set_generation
();
return
cur_head
;
}
}
...
...
@@ -570,6 +573,51 @@ bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool sum
return
false
;
}
// Whitebox API for blocking until the current generation of NMT data has been merged
bool
MemTracker
::
wbtest_wait_for_data_merge
()
{
// NMT can't be shutdown while we're holding _query_lock
MutexLockerEx
lock
(
_query_lock
,
true
);
assert
(
_worker_thread
!=
NULL
,
"Invalid query"
);
// the generation at query time, so NMT will spin till this generation is processed
unsigned
long
generation_at_query_time
=
SequenceGenerator
::
current_generation
();
unsigned
long
current_processing_generation
=
_processing_generation
;
// if generation counter overflown
bool
generation_overflown
=
(
generation_at_query_time
<
current_processing_generation
);
long
generations_to_wrap
=
MAX_UNSIGNED_LONG
-
current_processing_generation
;
// spin
while
(
!
shutdown_in_progress
())
{
if
(
!
generation_overflown
)
{
if
(
current_processing_generation
>
generation_at_query_time
)
{
return
true
;
}
}
else
{
assert
(
generations_to_wrap
>=
0
,
"Sanity check"
);
long
current_generations_to_wrap
=
MAX_UNSIGNED_LONG
-
current_processing_generation
;
assert
(
current_generations_to_wrap
>=
0
,
"Sanity check"
);
// to overflow an unsigned long should take long time, so to_wrap check should be sufficient
if
(
current_generations_to_wrap
>
generations_to_wrap
&&
current_processing_generation
>
generation_at_query_time
)
{
return
true
;
}
}
// if worker thread is idle, but generation is not advancing, that means
// there is not safepoint to let NMT advance generation, force one.
if
(
_worker_thread_idle
)
{
VM_ForceSafepoint
vfs
;
VMThread
::
execute
(
&
vfs
);
}
MemSnapshot
*
snapshot
=
get_snapshot
();
if
(
snapshot
==
NULL
)
{
return
false
;
}
snapshot
->
wait
(
1000
);
current_processing_generation
=
_processing_generation
;
}
// We end up here if NMT is shutting down before our data has been merged
return
false
;
}
// compare memory usage between current snapshot and baseline
bool
MemTracker
::
compare_memory_usage
(
BaselineOutputer
&
out
,
size_t
unit
,
bool
summary_only
)
{
MutexLockerEx
lock
(
_query_lock
,
true
);
...
...
hotspot/src/share/vm/services/memTracker.hpp
浏览文件 @
f09ff5c1
...
...
@@ -91,9 +91,10 @@ class MemTracker : AllStatic {
static
bool
compare_memory_usage
(
BaselineOutputer
&
out
,
size_t
unit
,
bool
summary_only
=
true
)
{
}
static
bool
wbtest_wait_for_data_merge
()
{
}
static
inline
void
sync
()
{
}
static
inline
void
thread_exiting
(
JavaThread
*
thread
)
{
}
};
...
...
@@ -111,6 +112,10 @@ class MemTracker : AllStatic {
extern
bool
NMT_track_callsite
;
#ifndef MAX_UNSIGNED_LONG
#define MAX_UNSIGNED_LONG (unsigned long)(-1)
#endif
#ifdef ASSERT
#define DEBUG_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
#else
...
...
@@ -380,6 +385,11 @@ class MemTracker : AllStatic {
static
bool
compare_memory_usage
(
BaselineOutputer
&
out
,
size_t
unit
,
bool
summary_only
=
true
);
// the version for whitebox testing support, it ensures that all memory
// activities before this method call, are reflected in the snapshot
// database.
static
bool
wbtest_wait_for_data_merge
();
// sync is called within global safepoint to synchronize nmt data
static
void
sync
();
...
...
@@ -432,6 +442,15 @@ class MemTracker : AllStatic {
static
void
create_record_in_recorder
(
address
addr
,
MEMFLAGS
type
,
size_t
size
,
address
pc
,
JavaThread
*
thread
);
static
void
set_current_processing_generation
(
unsigned
long
generation
)
{
_worker_thread_idle
=
false
;
_processing_generation
=
generation
;
}
static
void
report_worker_idle
()
{
_worker_thread_idle
=
true
;
}
private:
// global memory snapshot
static
MemSnapshot
*
_snapshot
;
...
...
@@ -483,6 +502,11 @@ class MemTracker : AllStatic {
static
volatile
enum
NMTStates
_state
;
// the reason for shutting down nmt
static
enum
ShutdownReason
_reason
;
// the generation that NMT is processing
static
volatile
unsigned
long
_processing_generation
;
// although NMT is still procesing current generation, but
// there is not more recorder to process, set idle state
static
volatile
bool
_worker_thread_idle
;
};
#endif // !INCLUDE_NMT
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录