Java Heap
包含三个部分
YoungGen,OldGen,PermGen
三个部分,亦叫作年轻代,年老代,永久代。
DefNewGeneration
是
YoungGen
的一个实现,包含
_eden_space,
_from_space, _to_space
三个部分。在
YoungGen
中分配对象的时候会在
eden
中进行分配,
from
和
to
是在
ygc
的过程中用到的,将
eden
和
from
中存活的对象拷贝到
to
中,每一次ygc,from和to的角色会对调一下
ConcurrentMarkSweepGeneration
是
OldGen
的一个实现,这里存储的是经过
ygc
后,
age
较大的对象,或者是很大的对象
(
在
Young Gen
中分配不了的
)
,或者是
ygc
的时候
to
的区域受限存不了的对象也会晋升到
OldGen
中
PermGen
是存储
class
信息,常量池等等一些信息。
-
2.Java
Heap
在
Hotspot
中是如何创建、分配的
Java Heap
的创建经过下面几层路径,层层下去,最终完成创建,分配。
Thread.cpp,Create_VM
-> Arguments::parse -> init_globals() -> universe_init() -> Universe::initialize_heap()
在上面的路径中,在
JVM
初始化阶段,会先分析传进来的
java
参数,将一些变量进行修改或者初始化。
从
Universe::initialize_heap()
开始创建、分配
java
heap
。
2.1
创建
CollectorPolicy
这里根据传进来的参数,创建合适的
CollectorPolicy
,即给相应的
Generation
,包括
YoungGen,OldGen,PermGen
设置好相应的描述参数,最终会创建
GenerationSpec
来描述每一个
Generation
,根据
GenerationSpec
去创建
Generatiion
。
在
Universe::initialize_heap()
函数中有下面的代码
if (UseParallelGC) {
#ifndef SERIALGC
Universe::_collectedHeap = new ParallelScavengeHeap();
#else // SERIALGC
fatal("UseParallelGC not supported in java kernel vm.");
#endif // SERIALGC
} else if (UseG1GC) {
#ifndef SERIALGC
G1CollectorPolicy* g1p = new G1CollectorPolicy_BestRegionsFirst();
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
Universe::_collectedHeap = g1h;
#else // SERIALGC
fatal("UseG1GC not supported in java kernel vm.");
#endif // SERIALGC
} else {
GenCollectorPolicy *gc_policy;
if (UseSerialGC) {
gc_policy = new MarkSweepPolicy();
} else if (UseConcMarkSweepGC) {
#ifndef SERIALGC
if (UseAdaptiveSizePolicy) {
gc_policy = new ASConcurrentMarkSweepPolicy();
} else {
gc_policy = new ConcurrentMarkSweepPolicy();
}
#else // SERIALGC
fatal("UseConcMarkSweepGC not supported in java kernel vm.");
#endif // SERIALGC
} else { // default old generation
gc_policy = new MarkSweepPolicy();
}
Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
}
从这段代码中可以看出,根据一些参数的值,例如
UseConcMarkSweepGC
、
UseSerialGC
、
UseParallelGC
等等,选择何种
gc
策略,进而选择使用什么样的
heap
。
以
ParNew
和
Cms
为例来说,会执行到
gc_policy = new ConcurrentMarkSweepPolicy();
这一句,
ConcurrentMarkSweepPolicy
的继承关系结构如下
class ConcurrentMarkSweepPolicy : public TwoGenerationCollectorPolicy {
class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
class GenCollectorPolicy : public CollectorPolicy {
class CollectorPolicy : public CHeapObj {
protected:
size_t _initial_heap_byte_size;
size_t _max_heap_byte_size;
size_t _min_heap_byte_size;
size_t _min_alignment;
size_t _max_alignment;
}
在
ConcurrentMarkSweepPolicy
的构造函数中,会执行下面一些操作。构造函数执行的次序如下。
1.CollectorPolicy
,简单初始化一些参数
_min_alignment(1),
_max_alignment(1),
_initial_heap_byte_size(0),
_max_heap_byte_size(0),
_min_heap_byte_size(0),
2.GenCollectorPolicy
,默认构造
3.TwoGenerationCollectorPolicy
,默认构造
4.ConcurrentMarkSweepPolicy
调用了
initialize_all()
initialize_all();GenCollectorPolicy
的虚函数
virtual void initialize_all() {
initialize_flags();
initialize_size_info();
initialize_generations();
}
接下来分析上面提到的三个初始化函数。
1.initialize_flags()
// 设置调整jvm 参数的值,实际上也就是PermGen的一些参数,CollectorPolicy methods,包括MaxPermSize,PermSize,SharedReadOnlySize,SharedReadWriteSize,SharedMiscDataSize
void CollectorPolicy::initialize_flags() {
// 设置调整jvm 参数的值,包括NewSize,MaxNewSize,SurvivorRatio
void GenCollectorPolicy::initialize_flags() {
// 设置最小对齐65536=64k
set_min_alignment((uintx) Generation::GenGrain);
// 设置最大对齐card_size * os::vm_page
set_max_alignment(compute_max_alignment());
}
/// 设置调整jvm 参数的值,包括OldSize,MaxHeapSize
TwoGenerationCollectorPolicy::initialize_flags
2.initialize_size_info();
//设置_initial_heap_byte_size,_max_heap_byte_size,_min_heap_byte_size
CollectorPolicy::initialize_size_info(){
}
//设置gen[0]
GenCollectorPolicy::initialize_size_info(){
set_min_gen0_size(max_new_size);
set_initial_gen0_size(max_new_size);
set_max_gen0_size(max_new_size);
}
//设置gen[1], _min_gen1_size, _max_gen1_size, _initial_gen1_size
TwoGenerationCollectorPolicy::initialize_size_info(){
}
3.initialize_generations();
ConcurrentMarkSweepPolicy::initialize_generations(){
CollectorPolicy::initialize_perm_generation(),初始化PermGenSpec
_generations = new GenerationSpecPtr[number_of_generations()];//分代,为2
//ParNewGen::in_user()
_generations[0] = new GenerationSpec(Generation::ParNew,
_initial_gen0_size, _max_gen0_size);
_generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep,
_initial_gen1_size, _max_gen1_size);
//NewGen ,OldGen, PermGen
//NewGen+OldGen = MaxHeapSize
New GenCollectedHeap();初始化gc的workgroup WorkGang
}
2.2
创建
GenCollectedHeap
在创建完
CollectorPolicy
之后,会创建
GenCollectedHeap
。在创建
GenCollectedHeap
中,没有进行真正分配空间,只是初始化了一些参数而已,真正的分配空间是在
Universe::heap()->initialize()
中进行的。
3.2Java Heap
分配
创建
GenCollectedHeap
后,会有初始化的代码,
Universe::heap()->initialize();
这里调用了
GenCollectedHeap::initialize()
,主要代码及注释如下所示。
{
//分配区域,由heap_rs保存,三个区域:YoungGen,OldGen,PermGen
heap_address = allocate(alignment, perm_gen_spec, &n_covered_regions,
&n_covered_regions, &heap_rs);
//_reserved区域包括Y,O,P三个区域
_reserved = MemRegion((HeapWord*)heap_rs.base(),
(HeapWord*)(heap_rs.base() + heap_rs.size()));
_reserved.set_word_size(0);
_reserved.set_start((HeapWord*)heap_rs.base());
size_t actual_heap_size = heap_rs.size() - perm_gen_spec->misc_data_size()
- perm_gen_spec->misc_code_size();
_reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size));
//_rem_set管理的_reserved区域为分配的整体内存,包括三个部分Y,O,P
_rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);
set_barrier_set(rem_set()->bs());
//将_reserved区域划分到对应的二个Y,O区域,并init
for (i = 0; i < _n_gens; i++) {
ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(),
UseSharedSpaces, UseSharedSpaces);
_gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());
heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());
}
//划分剩余的区域到perm gen,并init
_perm_gen = perm_gen_spec->init(heap_rs, PermSize, rem_set());
}
从代码中看出,这里是根据之前的
generationspec
,通过
allocate
函数分配出空间,包括
YoungGen,OldGen,PermGen
,然后保存在
_reserved
中,
_reserved
会设置实际的
heap
空间为去掉
PermGen
中的
msic_data
和
msic_code
的空间;接下来会创建一个
BarrierSet
,这是一个覆盖整个
_reserved
实际空间的数组,数组中每个
byte
对应
heap
中的
512B(
根据
BarrierSet
中常量设置有关
)
;最后会依次初始化
YoungGen,OldGen,PermGen
。
JVM
会根据传进来的参数选择
gc
算法,
gc
算法确定后,
CollectorPolicy
就会确定了,确定完
collectorpolicy
就能知道
GenerationSpec
,然后创建
GenCollectedHeap
,根据
GenerationSpec
初始化
JavaHeap
中的
YoungGen,OldGen,PermGen
。
分享到:
相关推荐
Java 11版本中的HotSpot虚拟机,与之前版本相比,引入了新的垃圾回收器(Epsilon垃圾回收器)、新的HTTP客户端API、支持新的HTTP/2协议等特性。 最后,文档强调,尽管Oracle的软件是为了普通用途的信息管理应用开发...
在JDK 1.8中,还有一项重要改进是 Nashorn JavaScript引擎的引入,这使得Java可以直接运行JavaScript代码,促进了Java与JavaScript之间的互操作性。 为了便于开发,JDK 1.8还包括了增强的调试工具,如JConsole和...
《Memory Management in the Java HotSpot™ Virtual Machine》一文深入探讨了Java HotSpot虚拟机中的内存管理机制,这是Java性能优化的关键领域。HotSpot虚拟机是Oracle JDK和JRE的一部分,以其高性能和优化能力而...
java 虚拟机 hotspot 源码
《Java SE 6与HotSpot VM故障排除指南》是Oracle公司于2008年11月发布的一份技术文档,旨在帮助开发人员、系统管理员和技术支持人员解决在使用Java Standard Edition 6 (Java SE 6) 和HotSpot虚拟机过程中遇到的各种...
学习JDK 源码必备,提起HotSpot VM,相信所有Java程序员都知道,它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。 但不一定所有人都知道的是,这个目前看起来“血统纯正”的虚拟机在最初...
### Java HotSpot 性能引擎架构相关知识点 #### 一、引言与概览 **Java HotSpot 虚拟机**是 Sun 公司针对 Java 平台设计的一款高性能虚拟机,它作为 Java SE 平台的核心组件,为商业关键型应用提供了强大的支持。...
本文将详细介绍 HotSpot 中与 Java 方法调用相关的 StubCode,特别是通过 `JavaCalls` 类中的方法调用来理解其内部机制。 #### JavaCalls 类详解 在 HotSpot 的源代码中,`JavaCalls` 类位于 `hotspot/src/share/...
【标题】"hotspot-8.rar" 涉及的核心知识点是HotSpot虚拟机和JVM(Java Virtual Machine)的学习,这是一款由Oracle公司开发的Java虚拟机实现,广泛应用于Java程序的运行与优化。HotSpot是Java平台的重要组成部分,...
在HotSpot中,线程类型包括虚拟机工作线程(如GC线程)和用户自定义线程(即JavaThread,对应用户创建的`Thread`实例)。JavaThread是一个CHeapObj的子类,存储在C的堆中,不受垃圾回收管理。 3. **Linux内核层**:...
《HotSpot实战》这本书深入探讨了Java开发中的关键组件——HotSpot虚拟机。HotSpot是Oracle JDK和OpenJDK中的默认Java虚拟机,它在Java应用程序的运行时性能优化方面扮演着重要角色。以下是该书可能涵盖的一些核心...
本文档提供了Java HotSpot虚拟机(JVM)中内存管理的广泛概述,特别是在Sun公司的Java 2平台标准版(J2SE)5.0版本的发布中。文档描述了可供使用的垃圾收集器(Garbage Collectors),给出了关于如何选择和配置收集...
《Java HotSpot 虚拟机》文件中包含了关于Java虚拟机(JVM)的深入讨论,尤其是在HotSpot虚拟机上的即时编译(JIT)技术,以及Java语言的最新发展。文件内容侧重于以下几个核心知识点: 1. **Java HotSpot虚拟机的...
java openJDK 源码, Hotspot, 未编译, 原始代码, 直接zip压缩包, java openJDK 源码, Hotspot, 未编译, 原始代码, 直接zip压缩包, java openJDK 源码, Hotspot, 未编译, 原始代码, 直接zip压缩包
【标题】"jdk-8.0.302.8-hotspot" 是Oracle公司发布的Java Development Kit(JDK)的一个版本,它包含了Java运行时环境(JRE)和用于开发Java应用程序的工具。这个特定的版本是8u302,意味着它是Java 8的更新302版,...
《深入解析JDK7:基于C++的底层源码与HotSpot虚拟机剖析》 在IT领域,Java作为一门广泛使用的编程语言,其性能优化和内部机制一直是开发者关注的焦点。JDK7作为Java发展历程中的一个重要版本,引入了许多创新特性,...
HotSpot VM,作为Java开发人员耳熟能详的名字,是Sun JDK和OpenJDK中的核心组件,它的普及程度无出其右。HotSpot以其高效性能、优秀的垃圾回收机制以及丰富的优化手段,赢得了全球Java开发者的一致青睐。本文将围绕...
4. **虚拟机接口模块**:提供与Java语言交互的接口,包括JNI(Java Native Interface)和JVM TI(Java Virtual Machine Tool Interface),它们允许C/C++代码与Java代码交互,以及调试和监控工具接入。 5. **服务...
Hotspot实现了Java线程模型,并且优化了线程创建、调度和同步原语。通过源码,我们可以深入理解Java线程的实现,以及如何优化线程池和并发程序。 8. **性能监控与诊断工具** Hotspot提供了丰富的性能监控和诊断...