Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
c22b626d
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看板
提交
c22b626d
编写于
12月 11, 2017
作者:
M
mchinnathamb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8170395: Metaspace initialization queries the wrong chunk freelist
Reviewed-by: stuefe, stefank
上级
f08a9816
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
196 addition
and
107 deletion
+196
-107
src/share/vm/memory/metaspace.cpp
src/share/vm/memory/metaspace.cpp
+172
-99
src/share/vm/memory/metaspace.hpp
src/share/vm/memory/metaspace.hpp
+10
-5
src/share/vm/prims/jni.cpp
src/share/vm/prims/jni.cpp
+3
-1
src/share/vm/utilities/debug.cpp
src/share/vm/utilities/debug.cpp
+9
-1
src/share/vm/utilities/debug.hpp
src/share/vm/utilities/debug.hpp
+2
-1
未找到文件。
src/share/vm/memory/metaspace.cpp
浏览文件 @
c22b626d
...
@@ -531,9 +531,8 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
...
@@ -531,9 +531,8 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
size_t
free_bytes
();
size_t
free_bytes
();
Metachunk
*
get_new_chunk
(
size_t
word_size
,
Metachunk
*
get_new_chunk
(
size_t
chunk_word_size
,
size_t
grow_chunks_by_words
,
size_t
suggested_commit_granularity
);
size_t
medium_chunk_bunch
);
bool
expand_node_by
(
VirtualSpaceNode
*
node
,
bool
expand_node_by
(
VirtualSpaceNode
*
node
,
size_t
min_words
,
size_t
min_words
,
...
@@ -687,15 +686,22 @@ class SpaceManager : public CHeapObj<mtClass> {
...
@@ -687,15 +686,22 @@ class SpaceManager : public CHeapObj<mtClass> {
MediumChunkMultiple
=
4
MediumChunkMultiple
=
4
};
};
bool
is_class
()
{
return
_mdtype
==
Metaspace
::
ClassType
;
}
static
size_t
specialized_chunk_size
(
bool
is_class
)
{
return
is_class
?
ClassSpecializedChunk
:
SpecializedChunk
;
}
static
size_t
small_chunk_size
(
bool
is_class
)
{
return
is_class
?
ClassSmallChunk
:
SmallChunk
;
}
static
size_t
medium_chunk_size
(
bool
is_class
)
{
return
is_class
?
ClassMediumChunk
:
MediumChunk
;
}
static
size_t
smallest_chunk_size
(
bool
is_class
)
{
return
specialized_chunk_size
(
is_class
);
}
// Accessors
// Accessors
size_t
specialized_chunk_size
()
{
return
(
size_t
)
is_class
()
?
ClassSpecializedChunk
:
SpecializedChunk
;
}
bool
is_class
()
const
{
return
_mdtype
==
Metaspace
::
ClassType
;
}
size_t
small_chunk_size
()
{
return
(
size_t
)
is_class
()
?
ClassSmallChunk
:
SmallChunk
;
}
size_t
medium_chunk_size
()
{
return
(
size_t
)
is_class
()
?
ClassMediumChunk
:
MediumChunk
;
}
size_t
specialized_chunk_size
()
const
{
return
specialized_chunk_size
(
is_class
());
}
size_t
medium_chunk_bunch
()
{
return
medium_chunk_size
()
*
MediumChunkMultiple
;
}
size_t
small_chunk_size
()
const
{
return
small_chunk_size
(
is_class
());
}
size_t
medium_chunk_size
()
const
{
return
medium_chunk_size
(
is_class
());
}
size_t
smallest_chunk_size
()
{
return
specialized_chunk_size
();
}
size_t
smallest_chunk_size
()
const
{
return
smallest_chunk_size
(
is_class
());
}
size_t
medium_chunk_bunch
()
const
{
return
medium_chunk_size
()
*
MediumChunkMultiple
;
}
size_t
allocated_blocks_words
()
const
{
return
_allocated_blocks_words
;
}
size_t
allocated_blocks_words
()
const
{
return
_allocated_blocks_words
;
}
size_t
allocated_blocks_bytes
()
const
{
return
_allocated_blocks_words
*
BytesPerWord
;
}
size_t
allocated_blocks_bytes
()
const
{
return
_allocated_blocks_words
*
BytesPerWord
;
}
...
@@ -718,10 +724,13 @@ class SpaceManager : public CHeapObj<mtClass> {
...
@@ -718,10 +724,13 @@ class SpaceManager : public CHeapObj<mtClass> {
// decremented for all the Metachunks in-use by this SpaceManager.
// decremented for all the Metachunks in-use by this SpaceManager.
void
dec_total_from_size_metrics
();
void
dec_total_from_size_metrics
();
// Set the sizes for the initial chunks.
// Adjust the initial chunk size to match one of the fixed chunk list sizes,
void
get_initial_chunk_sizes
(
Metaspace
::
MetaspaceType
type
,
// or return the unadjusted size if the requested size is humongous.
size_t
*
chunk_word_size
,
static
size_t
adjust_initial_chunk_size
(
size_t
requested
,
bool
is_class_space
);
size_t
*
class_chunk_word_size
);
size_t
adjust_initial_chunk_size
(
size_t
requested
)
const
;
// Get the initial chunks size for this metaspace type.
size_t
get_initial_chunk_size
(
Metaspace
::
MetaspaceType
type
)
const
;
size_t
sum_capacity_in_chunks_in_use
()
const
;
size_t
sum_capacity_in_chunks_in_use
()
const
;
size_t
sum_used_in_chunks_in_use
()
const
;
size_t
sum_used_in_chunks_in_use
()
const
;
...
@@ -732,7 +741,7 @@ class SpaceManager : public CHeapObj<mtClass> {
...
@@ -732,7 +741,7 @@ class SpaceManager : public CHeapObj<mtClass> {
size_t
sum_count_in_chunks_in_use
();
size_t
sum_count_in_chunks_in_use
();
size_t
sum_count_in_chunks_in_use
(
ChunkIndex
i
);
size_t
sum_count_in_chunks_in_use
(
ChunkIndex
i
);
Metachunk
*
get_new_chunk
(
size_t
word_size
,
size_t
grow_chunks_by_words
);
Metachunk
*
get_new_chunk
(
size_t
chunk_word_size
);
// Block allocation and deallocation.
// Block allocation and deallocation.
// Allocates a block from the current chunk
// Allocates a block from the current chunk
...
@@ -1319,12 +1328,10 @@ bool VirtualSpaceList::expand_by(size_t min_words, size_t preferred_words) {
...
@@ -1319,12 +1328,10 @@ bool VirtualSpaceList::expand_by(size_t min_words, size_t preferred_words) {
return
false
;
return
false
;
}
}
Metachunk
*
VirtualSpaceList
::
get_new_chunk
(
size_t
word_size
,
Metachunk
*
VirtualSpaceList
::
get_new_chunk
(
size_t
chunk_word_size
,
size_t
suggested_commit_granularity
)
{
size_t
grow_chunks_by_words
,
size_t
medium_chunk_bunch
)
{
// Allocate a chunk out of the current virtual space.
// Allocate a chunk out of the current virtual space.
Metachunk
*
next
=
current_virtual_space
()
->
get_chunk_vs
(
grow_chunks_by_words
);
Metachunk
*
next
=
current_virtual_space
()
->
get_chunk_vs
(
chunk_word_size
);
if
(
next
!=
NULL
)
{
if
(
next
!=
NULL
)
{
return
next
;
return
next
;
...
@@ -1333,8 +1340,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
...
@@ -1333,8 +1340,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
// The expand amount is currently only determined by the requested sizes
// The expand amount is currently only determined by the requested sizes
// and not how much committed memory is left in the current virtual space.
// and not how much committed memory is left in the current virtual space.
size_t
min_word_size
=
align_size_up
(
grow_chunks_by_words
,
Metaspace
::
commit_alignment_words
());
size_t
min_word_size
=
align_size_up
(
chunk_word_size
,
Metaspace
::
commit_alignment_words
());
size_t
preferred_word_size
=
align_size_up
(
medium_chunk_bunch
,
Metaspace
::
commit_alignment_words
());
size_t
preferred_word_size
=
align_size_up
(
suggested_commit_granularity
,
Metaspace
::
commit_alignment_words
());
if
(
min_word_size
>=
preferred_word_size
)
{
if
(
min_word_size
>=
preferred_word_size
)
{
// Can happen when humongous chunks are allocated.
// Can happen when humongous chunks are allocated.
preferred_word_size
=
min_word_size
;
preferred_word_size
=
min_word_size
;
...
@@ -1342,7 +1349,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
...
@@ -1342,7 +1349,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
bool
expanded
=
expand_by
(
min_word_size
,
preferred_word_size
);
bool
expanded
=
expand_by
(
min_word_size
,
preferred_word_size
);
if
(
expanded
)
{
if
(
expanded
)
{
next
=
current_virtual_space
()
->
get_chunk_vs
(
grow_chunks_by_words
);
next
=
current_virtual_space
()
->
get_chunk_vs
(
chunk_word_size
);
assert
(
next
!=
NULL
,
"The allocation was expected to succeed after the expansion"
);
assert
(
next
!=
NULL
,
"The allocation was expected to succeed after the expansion"
);
}
}
...
@@ -1883,36 +1890,58 @@ void ChunkManager::print_on(outputStream* out) const {
...
@@ -1883,36 +1890,58 @@ void ChunkManager::print_on(outputStream* out) const {
// SpaceManager methods
// SpaceManager methods
void
SpaceManager
::
get_initial_chunk_sizes
(
Metaspace
::
MetaspaceType
type
,
size_t
SpaceManager
::
adjust_initial_chunk_size
(
size_t
requested
,
bool
is_class_space
)
{
size_t
*
chunk_word_size
,
size_t
chunk_sizes
[]
=
{
size_t
*
class_chunk_word_size
)
{
specialized_chunk_size
(
is_class_space
),
switch
(
type
)
{
small_chunk_size
(
is_class_space
),
case
Metaspace
::
BootMetaspaceType
:
medium_chunk_size
(
is_class_space
)
*
chunk_word_size
=
Metaspace
::
first_chunk_word_size
();
};
*
class_chunk_word_size
=
Metaspace
::
first_class_chunk_word_size
();
break
;
// Adjust up to one of the fixed chunk sizes ...
case
Metaspace
::
ROMetaspaceType
:
for
(
size_t
i
=
0
;
i
<
ARRAY_SIZE
(
chunk_sizes
);
i
++
)
{
*
chunk_word_size
=
SharedReadOnlySize
/
wordSize
;
if
(
requested
<=
chunk_sizes
[
i
])
{
*
class_chunk_word_size
=
ClassSpecializedChunk
;
return
chunk_sizes
[
i
];
break
;
}
case
Metaspace
::
ReadWriteMetaspaceType
:
}
*
chunk_word_size
=
SharedReadWriteSize
/
wordSize
;
*
class_chunk_word_size
=
ClassSpecializedChunk
;
// ... or return the size as a humongous chunk.
break
;
return
requested
;
case
Metaspace
::
AnonymousMetaspaceType
:
}
case
Metaspace
::
ReflectionMetaspaceType
:
*
chunk_word_size
=
SpecializedChunk
;
size_t
SpaceManager
::
adjust_initial_chunk_size
(
size_t
requested
)
const
{
*
class_chunk_word_size
=
ClassSpecializedChunk
;
return
adjust_initial_chunk_size
(
requested
,
is_class
());
break
;
}
default:
*
chunk_word_size
=
SmallChunk
;
size_t
SpaceManager
::
get_initial_chunk_size
(
Metaspace
::
MetaspaceType
type
)
const
{
*
class_chunk_word_size
=
ClassSmallChunk
;
size_t
requested
;
break
;
}
if
(
is_class
())
{
assert
(
*
chunk_word_size
!=
0
&&
*
class_chunk_word_size
!=
0
,
switch
(
type
)
{
err_msg
(
"Initial chunks sizes bad: data "
SIZE_FORMAT
case
Metaspace
::
BootMetaspaceType
:
requested
=
Metaspace
::
first_class_chunk_word_size
();
break
;
" class "
SIZE_FORMAT
,
case
Metaspace
::
ROMetaspaceType
:
requested
=
ClassSpecializedChunk
;
break
;
*
chunk_word_size
,
*
class_chunk_word_size
));
case
Metaspace
::
ReadWriteMetaspaceType
:
requested
=
ClassSpecializedChunk
;
break
;
case
Metaspace
::
AnonymousMetaspaceType
:
requested
=
ClassSpecializedChunk
;
break
;
case
Metaspace
::
ReflectionMetaspaceType
:
requested
=
ClassSpecializedChunk
;
break
;
default:
requested
=
ClassSmallChunk
;
break
;
}
}
else
{
switch
(
type
)
{
case
Metaspace
::
BootMetaspaceType
:
requested
=
Metaspace
::
first_chunk_word_size
();
break
;
case
Metaspace
::
ROMetaspaceType
:
requested
=
SharedReadOnlySize
/
wordSize
;
break
;
case
Metaspace
::
ReadWriteMetaspaceType
:
requested
=
SharedReadWriteSize
/
wordSize
;
break
;
case
Metaspace
::
AnonymousMetaspaceType
:
requested
=
SpecializedChunk
;
break
;
case
Metaspace
::
ReflectionMetaspaceType
:
requested
=
SpecializedChunk
;
break
;
default:
requested
=
SmallChunk
;
break
;
}
}
// Adjust to one of the fixed chunk sizes (unless humongous)
const
size_t
adjusted
=
adjust_initial_chunk_size
(
requested
);
assert
(
adjusted
!=
0
,
err_msg
(
"Incorrect initial chunk size. Requested: "
SIZE_FORMAT
" adjusted: "
SIZE_FORMAT
,
requested
,
adjusted
));
return
adjusted
;
}
}
size_t
SpaceManager
::
sum_free_in_chunks_in_use
()
const
{
size_t
SpaceManager
::
sum_free_in_chunks_in_use
()
const
{
...
@@ -2102,8 +2131,8 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
...
@@ -2102,8 +2131,8 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
}
}
// Get another chunk out of the virtual space
// Get another chunk out of the virtual space
size_t
grow_chunks_by_words
=
calc_chunk_size
(
word_size
);
size_t
chunk_word_size
=
calc_chunk_size
(
word_size
);
Metachunk
*
next
=
get_new_chunk
(
word_size
,
grow_chunks_by_words
);
Metachunk
*
next
=
get_new_chunk
(
chunk_word_size
);
MetaWord
*
mem
=
NULL
;
MetaWord
*
mem
=
NULL
;
...
@@ -2412,14 +2441,12 @@ void SpaceManager::retire_current_chunk() {
...
@@ -2412,14 +2441,12 @@ void SpaceManager::retire_current_chunk() {
}
}
}
}
Metachunk
*
SpaceManager
::
get_new_chunk
(
size_t
word_size
,
Metachunk
*
SpaceManager
::
get_new_chunk
(
size_t
chunk_word_size
)
{
size_t
grow_chunks_by_words
)
{
// Get a chunk from the chunk freelist
// Get a chunk from the chunk freelist
Metachunk
*
next
=
chunk_manager
()
->
chunk_freelist_allocate
(
grow_chunks_by_words
);
Metachunk
*
next
=
chunk_manager
()
->
chunk_freelist_allocate
(
chunk_word_size
);
if
(
next
==
NULL
)
{
if
(
next
==
NULL
)
{
next
=
vs_list
()
->
get_new_chunk
(
word_size
,
next
=
vs_list
()
->
get_new_chunk
(
chunk_word_size
,
grow_chunks_by_words
,
medium_chunk_bunch
());
medium_chunk_bunch
());
}
}
...
@@ -3085,7 +3112,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) {
...
@@ -3085,7 +3112,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) {
err_msg
(
SIZE_FORMAT
" != "
UINTX_FORMAT
,
rs
.
size
(),
CompressedClassSpaceSize
));
err_msg
(
SIZE_FORMAT
" != "
UINTX_FORMAT
,
rs
.
size
(),
CompressedClassSpaceSize
));
assert
(
using_class_space
(),
"Must be using class space"
);
assert
(
using_class_space
(),
"Must be using class space"
);
_class_space_list
=
new
VirtualSpaceList
(
rs
);
_class_space_list
=
new
VirtualSpaceList
(
rs
);
_chunk_manager_class
=
new
ChunkManager
(
SpecializedChunk
,
ClassSmallChunk
,
ClassMediumChunk
);
_chunk_manager_class
=
new
ChunkManager
(
Class
SpecializedChunk
,
ClassSmallChunk
,
ClassMediumChunk
);
if
(
!
_class_space_list
->
initialization_succeeded
())
{
if
(
!
_class_space_list
->
initialization_succeeded
())
{
vm_exit_during_initialization
(
"Failed to setup compressed class space virtual space list."
);
vm_exit_during_initialization
(
"Failed to setup compressed class space virtual space list."
);
...
@@ -3286,66 +3313,62 @@ void Metaspace::post_initialize() {
...
@@ -3286,66 +3313,62 @@ void Metaspace::post_initialize() {
MetaspaceGC
::
post_initialize
();
MetaspaceGC
::
post_initialize
();
}
}
Metachunk
*
Metaspace
::
get_initialization_chunk
(
MetadataType
mdtype
,
void
Metaspace
::
initialize_first_chunk
(
MetaspaceType
type
,
MetadataType
mdtype
)
{
size_t
chunk_word_size
,
Metachunk
*
chunk
=
get_initialization_chunk
(
type
,
mdtype
);
size_t
chunk_bunch
)
{
if
(
chunk
!=
NULL
)
{
// Add to this manager's list of chunks in use and current_chunk().
get_space_manager
(
mdtype
)
->
add_chunk
(
chunk
,
true
);
}
}
Metachunk
*
Metaspace
::
get_initialization_chunk
(
MetaspaceType
type
,
MetadataType
mdtype
)
{
size_t
chunk_word_size
=
get_space_manager
(
mdtype
)
->
get_initial_chunk_size
(
type
);
// Get a chunk from the chunk freelist
// Get a chunk from the chunk freelist
Metachunk
*
chunk
=
get_chunk_manager
(
mdtype
)
->
chunk_freelist_allocate
(
chunk_word_size
);
Metachunk
*
chunk
=
get_chunk_manager
(
mdtype
)
->
chunk_freelist_allocate
(
chunk_word_size
);
if
(
chunk
!=
NULL
)
{
return
chunk
;
if
(
chunk
==
NULL
)
{
chunk
=
get_space_list
(
mdtype
)
->
get_new_chunk
(
chunk_word_size
,
get_space_manager
(
mdtype
)
->
medium_chunk_bunch
());
}
}
return
get_space_list
(
mdtype
)
->
get_new_chunk
(
chunk_word_size
,
chunk_word_size
,
chunk_bunch
);
// For dumping shared archive, report error if allocation has failed.
if
(
DumpSharedSpaces
&&
chunk
==
NULL
)
{
report_insufficient_metaspace
(
MetaspaceAux
::
committed_bytes
()
+
chunk_word_size
*
BytesPerWord
);
}
return
chunk
;
}
}
void
Metaspace
::
initialize
(
Mutex
*
lock
,
MetaspaceType
type
)
{
void
Metaspace
::
verify_global_initialization
()
{
assert
(
space_list
()
!=
NULL
,
"Metadata VirtualSpaceList has not been initialized"
);
assert
(
chunk_manager_metadata
()
!=
NULL
,
"Metadata ChunkManager has not been initialized"
);
if
(
using_class_space
())
{
assert
(
class_space_list
()
!=
NULL
,
"Class VirtualSpaceList has not been initialized"
);
assert
(
chunk_manager_class
()
!=
NULL
,
"Class ChunkManager has not been initialized"
);
}
}
assert
(
space_list
()
!=
NULL
,
void
Metaspace
::
initialize
(
Mutex
*
lock
,
MetaspaceType
type
)
{
"Metadata VirtualSpaceList has not been initialized"
);
verify_global_initialization
();
assert
(
chunk_manager_metadata
()
!=
NULL
,
"Metadata ChunkManager has not been initialized"
);
// Allocate SpaceManager for metadata objects.
_vsm
=
new
SpaceManager
(
NonClassType
,
lock
);
_vsm
=
new
SpaceManager
(
NonClassType
,
lock
);
if
(
_vsm
==
NULL
)
{
return
;
}
size_t
word_size
;
size_t
class_word_size
;
vsm
()
->
get_initial_chunk_sizes
(
type
,
&
word_size
,
&
class_word_size
);
if
(
using_class_space
())
{
if
(
using_class_space
())
{
assert
(
class_space_list
()
!=
NULL
,
"Class VirtualSpaceList has not been initialized"
);
assert
(
chunk_manager_class
()
!=
NULL
,
"Class ChunkManager has not been initialized"
);
// Allocate SpaceManager for classes.
// Allocate SpaceManager for classes.
_class_vsm
=
new
SpaceManager
(
ClassType
,
lock
);
_class_vsm
=
new
SpaceManager
(
ClassType
,
lock
);
if
(
_class_vsm
==
NULL
)
{
return
;
}
}
}
MutexLockerEx
cl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
MutexLockerEx
cl
(
SpaceManager
::
expand_lock
(),
Mutex
::
_no_safepoint_check_flag
);
// Allocate chunk for metadata objects
// Allocate chunk for metadata objects
Metachunk
*
new_chunk
=
get_initialization_chunk
(
NonClassType
,
initialize_first_chunk
(
type
,
NonClassType
);
word_size
,
vsm
()
->
medium_chunk_bunch
());
assert
(
!
DumpSharedSpaces
||
new_chunk
!=
NULL
,
"should have enough space for both chunks"
);
if
(
new_chunk
!=
NULL
)
{
// Add to this manager's list of chunks in use and current_chunk().
vsm
()
->
add_chunk
(
new_chunk
,
true
);
}
// Allocate chunk for class metadata objects
// Allocate chunk for class metadata objects
if
(
using_class_space
())
{
if
(
using_class_space
())
{
Metachunk
*
class_chunk
=
get_initialization_chunk
(
ClassType
,
initialize_first_chunk
(
type
,
ClassType
);
class_word_size
,
class_vsm
()
->
medium_chunk_bunch
());
if
(
class_chunk
!=
NULL
)
{
class_vsm
()
->
add_chunk
(
class_chunk
,
true
);
}
}
}
_alloc_record_head
=
NULL
;
_alloc_record_head
=
NULL
;
...
@@ -3772,7 +3795,7 @@ class TestMetaspaceAuxTest : AllStatic {
...
@@ -3772,7 +3795,7 @@ class TestMetaspaceAuxTest : AllStatic {
// vm_allocation_granularity aligned on Windows.
// vm_allocation_granularity aligned on Windows.
size_t
large_size
=
(
size_t
)(
2
*
256
*
K
+
(
os
::
vm_page_size
()
/
BytesPerWord
));
size_t
large_size
=
(
size_t
)(
2
*
256
*
K
+
(
os
::
vm_page_size
()
/
BytesPerWord
));
large_size
+=
(
os
::
vm_page_size
()
/
BytesPerWord
);
large_size
+=
(
os
::
vm_page_size
()
/
BytesPerWord
);
vs_list
->
get_new_chunk
(
large_size
,
large_size
,
0
);
vs_list
->
get_new_chunk
(
large_size
,
0
);
}
}
static
void
test
()
{
static
void
test
()
{
...
@@ -3947,4 +3970,54 @@ void TestVirtualSpaceNode_test() {
...
@@ -3947,4 +3970,54 @@ void TestVirtualSpaceNode_test() {
TestVirtualSpaceNodeTest
::
test
();
TestVirtualSpaceNodeTest
::
test
();
TestVirtualSpaceNodeTest
::
test_is_available
();
TestVirtualSpaceNodeTest
::
test_is_available
();
}
}
// The following test is placed here instead of a gtest / unittest file
// because the ChunkManager class is only available in this file.
class
SpaceManagerTest
:
AllStatic
{
friend
void
SpaceManager_test_adjust_initial_chunk_size
();
static
void
test_adjust_initial_chunk_size
(
bool
is_class
)
{
const
size_t
smallest
=
SpaceManager
::
smallest_chunk_size
(
is_class
);
const
size_t
normal
=
SpaceManager
::
small_chunk_size
(
is_class
);
const
size_t
medium
=
SpaceManager
::
medium_chunk_size
(
is_class
);
#define test_adjust_initial_chunk_size(value, expected, is_class_value) \
do { \
size_t v = value; \
size_t e = expected; \
assert(SpaceManager::adjust_initial_chunk_size(v, (is_class_value)) == e, \
err_msg("Expected: " SIZE_FORMAT " got: " SIZE_FORMAT, e, v)); \
} while (0)
// Smallest (specialized)
test_adjust_initial_chunk_size
(
1
,
smallest
,
is_class
);
test_adjust_initial_chunk_size
(
smallest
-
1
,
smallest
,
is_class
);
test_adjust_initial_chunk_size
(
smallest
,
smallest
,
is_class
);
// Small
test_adjust_initial_chunk_size
(
smallest
+
1
,
normal
,
is_class
);
test_adjust_initial_chunk_size
(
normal
-
1
,
normal
,
is_class
);
test_adjust_initial_chunk_size
(
normal
,
normal
,
is_class
);
// Medium
test_adjust_initial_chunk_size
(
normal
+
1
,
medium
,
is_class
);
test_adjust_initial_chunk_size
(
medium
-
1
,
medium
,
is_class
);
test_adjust_initial_chunk_size
(
medium
,
medium
,
is_class
);
// Humongous
test_adjust_initial_chunk_size
(
medium
+
1
,
medium
+
1
,
is_class
);
#undef test_adjust_initial_chunk_size
}
static
void
test_adjust_initial_chunk_size
()
{
test_adjust_initial_chunk_size
(
false
);
test_adjust_initial_chunk_size
(
true
);
}
};
void
SpaceManager_test_adjust_initial_chunk_size
()
{
SpaceManagerTest
::
test_adjust_initial_chunk_size
();
}
#endif
#endif
src/share/vm/memory/metaspace.hpp
浏览文件 @
c22b626d
/*
/*
* Copyright (c) 2011, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -104,14 +104,15 @@ class Metaspace : public CHeapObj<mtClass> {
...
@@ -104,14 +104,15 @@ class Metaspace : public CHeapObj<mtClass> {
};
};
private:
private:
static
void
verify_global_initialization
();
void
initialize
(
Mutex
*
lock
,
MetaspaceType
type
);
void
initialize
(
Mutex
*
lock
,
MetaspaceType
type
);
//
Get
the first chunk for a Metaspace. Used for
//
Initialize
the first chunk for a Metaspace. Used for
// special cases such as the boot class loader, reflection
// special cases such as the boot class loader, reflection
// class loader and anonymous class loader.
// class loader and anonymous class loader.
Metachunk
*
get_initialization_chunk
(
MetadataType
mdtype
,
void
initialize_first_chunk
(
MetaspaceType
type
,
MetadataType
mdtype
);
size_t
chunk_word_size
,
Metachunk
*
get_initialization_chunk
(
MetaspaceType
type
,
MetadataType
mdtype
);
size_t
chunk_bunch
);
// Align up the word size to the allocation word size
// Align up the word size to the allocation word size
static
size_t
align_word_size_up
(
size_t
);
static
size_t
align_word_size_up
(
size_t
);
...
@@ -138,6 +139,10 @@ class Metaspace : public CHeapObj<mtClass> {
...
@@ -138,6 +139,10 @@ class Metaspace : public CHeapObj<mtClass> {
SpaceManager
*
_class_vsm
;
SpaceManager
*
_class_vsm
;
SpaceManager
*
class_vsm
()
const
{
return
_class_vsm
;
}
SpaceManager
*
class_vsm
()
const
{
return
_class_vsm
;
}
SpaceManager
*
get_space_manager
(
MetadataType
mdtype
)
{
assert
(
mdtype
!=
MetadataTypeCount
,
"MetadaTypeCount can't be used as mdtype"
);
return
mdtype
==
ClassType
?
class_vsm
()
:
vsm
();
}
// Allocate space for metadata of type mdtype. This is space
// Allocate space for metadata of type mdtype. This is space
// within a Metachunk and is used by
// within a Metachunk and is used by
...
...
src/share/vm/prims/jni.cpp
浏览文件 @
c22b626d
/*
/*
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 Red Hat, Inc.
* Copyright (c) 2012 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
...
@@ -5093,6 +5093,7 @@ void TestReservedSpace_test();
...
@@ -5093,6 +5093,7 @@ void TestReservedSpace_test();
void
TestReserveMemorySpecial_test
();
void
TestReserveMemorySpecial_test
();
void
TestVirtualSpace_test
();
void
TestVirtualSpace_test
();
void
TestMetaspaceAux_test
();
void
TestMetaspaceAux_test
();
void
SpaceManager_test_adjust_initial_chunk_size
();
void
TestMetachunk_test
();
void
TestMetachunk_test
();
void
TestVirtualSpaceNode_test
();
void
TestVirtualSpaceNode_test
();
void
TestNewSize_test
();
void
TestNewSize_test
();
...
@@ -5137,6 +5138,7 @@ void execute_internal_vm_tests() {
...
@@ -5137,6 +5138,7 @@ void execute_internal_vm_tests() {
run_unit_test
(
TestOldFreeSpaceCalculation_test
());
run_unit_test
(
TestOldFreeSpaceCalculation_test
());
run_unit_test
(
TestG1BiasedArray_test
());
run_unit_test
(
TestG1BiasedArray_test
());
run_unit_test
(
HeapRegionRemSet
::
test_prt
());
run_unit_test
(
HeapRegionRemSet
::
test_prt
());
run_unit_test
(
SpaceManager_test_adjust_initial_chunk_size
());
run_unit_test
(
TestBufferingOopClosure_test
());
run_unit_test
(
TestBufferingOopClosure_test
());
run_unit_test
(
TestCodeCacheRemSet_test
());
run_unit_test
(
TestCodeCacheRemSet_test
());
if
(
UseG1GC
)
{
if
(
UseG1GC
)
{
...
...
src/share/vm/utilities/debug.cpp
浏览文件 @
c22b626d
/*
/*
* Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -315,6 +315,14 @@ void report_java_out_of_memory(const char* message) {
...
@@ -315,6 +315,14 @@ void report_java_out_of_memory(const char* message) {
}
}
}
}
void
report_insufficient_metaspace
(
size_t
required_size
)
{
warning
(
"
\n
The MaxMetaspaceSize of "
SIZE_FORMAT
" bytes is not large enough.
\n
"
"Either don't specify the -XX:MaxMetaspaceSize=<size>
\n
"
"or increase the size to at least "
SIZE_FORMAT
".
\n
"
,
MaxMetaspaceSize
,
required_size
);
exit
(
2
);
}
static
bool
error_reported
=
false
;
static
bool
error_reported
=
false
;
// call this when the VM is dying--it might loosen some asserts
// call this when the VM is dying--it might loosen some asserts
...
...
src/share/vm/utilities/debug.hpp
浏览文件 @
c22b626d
/*
/*
* Copyright (c) 1997, 201
4
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -222,6 +222,7 @@ void report_should_not_call(const char* file, int line);
...
@@ -222,6 +222,7 @@ void report_should_not_call(const char* file, int line);
void
report_should_not_reach_here
(
const
char
*
file
,
int
line
);
void
report_should_not_reach_here
(
const
char
*
file
,
int
line
);
void
report_unimplemented
(
const
char
*
file
,
int
line
);
void
report_unimplemented
(
const
char
*
file
,
int
line
);
void
report_untested
(
const
char
*
file
,
int
line
,
const
char
*
message
);
void
report_untested
(
const
char
*
file
,
int
line
,
const
char
*
message
);
void
report_insufficient_metaspace
(
size_t
required_size
);
void
warning
(
const
char
*
format
,
...)
ATTRIBUTE_PRINTF
(
1
,
2
);
void
warning
(
const
char
*
format
,
...)
ATTRIBUTE_PRINTF
(
1
,
2
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录