jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理

进入Eden()->clean()函数
void EdenSpace::clear(bool mangle_space) {
ContiguousSpace::clear(mangle_space);
set_soft_end(end());
}
进入
void ContiguousSpace::clear(bool mangle_space) {
set_top(bottom());
set_saved_mark();
CompactibleSpace::clear(mangle_space);
}
打印对象,这个是eden
(gdb) p this
$154 = (EdenSpace * const) 0x7f4780020328
(gdb) p * this
$155 = (EdenSpace) {
<ContiguousSpace> = {
<CompactibleSpace> = {
<Space> = {
<CHeapObj<1280u>> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f4788515a90 <vtable for EdenSpace+16>
}, <No data fields>},
members of Space:
_bottom = 0xf3800000,
_end = 0xf5600000,
_saved_mark_word = 0xf4dccdb8,
_preconsumptionDirtyCardClosure = 0x0,
_par_seq_tasks = {
<StackObj> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f47884fb650 <vtable for SequentialSubTasksDone+16>
}, <No data fields>},
members of SequentialSubTasksDone:
_n_tasks = 0,
_n_claimed = 0,
_n_threads = 0,
_n_completed = 0
}
},
members of CompactibleSpace:
_compaction_top = 0xf3800000,
_next_compaction_space = 0x7f4780020438,
_first_dead = 0xf1f1f1f1f1f1f1f1,
_end_of_live = 0xf1f1f1f1f1f1f1f1
},
members of ContiguousSpace:
_top = 0xf4dccdb8,
_concurrent_iteration_safe_limit = 0xf3800000,
_mangler = 0x7f47800203e8
},
members of EdenSpace:
_gen = 0x7f478001f1c8,
_soft_end = 0xf5600000
}
看实现
(gdb) p bottom()
$156 = (HeapWord *) 0xf3800000
(gdb) p top()
$157 = (HeapWord *) 0xf4dccdb8
将top清空
设置mark
virtual void set_saved_mark() { _saved_mark_word = top(); }
清理完之后的对象
(gdb) p *this
$159 = (EdenSpace) {
<ContiguousSpace> = {
<CompactibleSpace> = {
<Space> = {
<CHeapObj<1280u>> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f4788515a90 <vtable for EdenSpace+16>
}, <No data fields>},
members of Space:
_bottom = 0xf3800000,
_end = 0xf5600000,
_saved_mark_word = 0xf3800000,
_preconsumptionDirtyCardClosure = 0x0,
_par_seq_tasks = {
<StackObj> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f47884fb650 <vtable for SequentialSubTasksDone+16>
}, <No data fields>},
members of SequentialSubTasksDone:
_n_tasks = 0,
_n_claimed = 0,
_n_threads = 0,
_n_completed = 0
}
},
members of CompactibleSpace:
_compaction_top = 0xf3800000,
_next_compaction_space = 0x7f4780020438,
_first_dead = 0xf1f1f1f1f1f1f1f1,
_end_of_live = 0xf1f1f1f1f1f1f1f1
},
members of ContiguousSpace:
_top = 0xf3800000,
_concurrent_iteration_safe_limit = 0xf3800000,
_mangler = 0x7f47800203e8
},
members of EdenSpace:
_gen = 0x7f478001f1c8,
_soft_end = 0xf5600000
}
接着看
CompactibleSpace::clear(mangle_space);
----------------------------------------------
void CompactibleSpace::clear(bool mangle_space) {
Space::clear(mangle_space);
_compaction_top = bottom();
}
----------------------------------------------
void Space::clear(bool mangle_space) {
if (ZapUnusedHeapArea && mangle_space) {
mangle_unused_area();
}
} -------------------------------------------------
void ContiguousSpace::mangle_unused_area() {
mangler()->mangle_unused_area();
}
-----------------------------------------------------
void SpaceMangler::mangle_unused_area() {
assert(ZapUnusedHeapArea, "Mangling should not be in use");
// Mangle between top and the high water mark. Safeguard
// against the space changing since top_for_allocations was
// set.
HeapWord* mangled_end = MIN2(top_for_allocations(), end());
if (top() < mangled_end) {
MemRegion mangle_mr(top(), mangled_end);
SpaceMangler::mangle_region(mangle_mr);
// Light weight check of mangling.
check_mangled_unused_area(end());
}
// Complete check of unused area which is functional when
// DEBUG_MANGLING is defined.
check_mangled_unused_area_complete();
}
打印这个spaceMangler对象
(gdb) p _mangler
$162 = (GenSpaceMangler *) 0x7f47800203e8
(gdb) p *_mangler
$163 = (GenSpaceMangler) {
<SpaceMangler> = {
<CHeapObj<1280u>> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f47885163d0 <vtable for GenSpaceMangler+16>
}, <No data fields>},
members of SpaceMangler:
_top_for_allocations = 0xf4dccdb8
},
members of GenSpaceMangler:
_sp = 0x7f4780020328
}
查看紫色函数
(gdb) p end()
$164 = (HeapWord *) 0xf5600000
(gdb) p _top_for_allocations
$165 = (HeapWord *) 0xf4dccdb8
进入棕色函数
// Simply mangle the MemRegion mr.
void SpaceMangler::mangle_region(MemRegion mr) {
assert(ZapUnusedHeapArea, "Mangling should not be in use");
#ifdef ASSERT
if(TraceZapUnusedHeapArea) {
gclog_or_tty->print("Mangling [0x%x to 0x%x)", mr.start(), mr.end());
}
Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord);
if(TraceZapUnusedHeapArea) {
gclog_or_tty->print_cr(" done");
}
#endif
}
进入函数
// Fill methods // Fill word-aligned words, not atomic on each word
// set_words
static void fill_to_words(HeapWord* to, size_t count, juint value = 0) {
assert_params_ok(to, LogHeapWordSize);
pd_fill_to_words(to, count, value);
}
进入
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
#ifdef AMD64
julong* to = (julong*) tohw;
julong v = ((julong) value << 32) | value;
while (count-- > 0) {
*to++ = v;
}
#else..无用..
#endif // AMD64
}
看badHeapWord的值
(gdb) p/x value
$171 = 0xbaadbabe
那么上述过程就是将heap的值全部设置成了0xbaadbabe
接着就是对from区域
(gdb) p from()
$175 = (ContiguousSpace *) 0x7f4780020438
重要的交换空间
swap_spaces();
交换之前
(gdb) p this
$181 = (DefNewGeneration * const) 0x7f478001f1c8
(gdb) p* this
$182 = (DefNewGeneration) {
<Generation> = {
<CHeapObj<1280u>> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f47884ff590 <vtable for DefNewGeneration+16>
}, <No data fields>},
members of Generation:
_time_of_last_gc = -1012762419733073423,
_prev_used_region = {
_start = 0x0,
_word_size = 0
},
_reserved = {
_start = 0xf3800000,
_word_size = 6553600
},
....略部分
_promo_failure_drain_in_progress = false,
_gen_counters = 0x7f4780020638,
_eden_counters = 0x7f478000d678,
_from_counters = 0x7f4780021888,
_to_counters = 0x7f4780021d78,
_max_eden_size = 31457280,
_max_survivor_size = 10485760,
_should_allocate_from_space = false,
_eden_space = 0x7f4780020328,
_from_space = 0x7f4780020438,
_to_space = 0x7f4780020538,
_gc_timer = 0x7f4780022268
}
代码为
void DefNewGeneration::swap_spaces() {
ContiguousSpace* s = from();
_from_space = to();
_to_space = s;
eden()->set_next_compaction_space(from());
// The to-space is normally empty before a compaction so need
// not be considered. The exception is during promotion
// failure handling when to-space can contain live objects.
from()->set_next_compaction_space(NULL);
if (UsePerfData) {
CSpaceCounters* c = _from_counters;
_from_counters = _to_counters;
_to_counters = c;
}
}
这个函数为 eden()->set_next_compaction_space(from());
void set_next_compaction_space(CompactibleSpace* csp) {
_next_compaction_space = csp;
}
将eden()的值设置为新的from值,(即原来的from空间已经变为了to空间)
if (UsePerfData) {
CSpaceCounters* c = _from_counters;
_from_counters = _to_counters;
_to_counters = c;
}
设置完成后就结束了
jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理的更多相关文章
- JVM 源码解读之 CMS 何时会进行 Full GC
t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...
- jvm源码解读--17 Java的wait()、notify()学习
write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...
- jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处
之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...
- jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析
粘贴源码 package com.test; import java.util.Random; public class Test { static int number=12; private in ...
- jvm源码解读--11 ldc指令的解读
写一个java文件 public static void main(String[] args) { String str1="abc"; String str2 ="a ...
- jvm源码解读--10 enum WKID 枚举
源码中对于枚举类型WKID的使用 static bool initialize_wk_klass(WKID id, int init_opt, TRAPS); static void initiali ...
- jvm源码解读--16 cas 用法解析
CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...
- jvm源码解读--06 Method 方法解析
进入 // Methods bool has_final_method = false; AccessFlags promoted_flags; promoted_flags.set_flags(0) ...
- jvm源码解读--15 oop对象详解
(gdb) p obj $15 = (oopDesc *) 0xf3885d08 (gdb) p * obj $16 = { _mark = 0x70dea4e01, _metadata = { _k ...
随机推荐
- 【NX二次开发】布尔操作
//布尔操作 //UF_MODL_operations 对两个体执行布尔操作 //UF_MODL_unite_bodies 相加布尔操作,不可保留目标体.工具体 //UF_MODL_unite_bod ...
- 『无为则无心』Python基础 — 8、Python中的数据类型(数值、布尔、字符串)
目录 1.数据类型介绍 2.数值型(Number) 3.布尔型(bool) 4.None(空值) 5.常量 6.字符串(String) 1.数据类型介绍 (1)什么是数据类型 在生活中,我们日常使用的 ...
- 微信小程序使用async await的一些技巧
在小程序onLoad事件中使用getItems(this) 和this.getItems() getItems(this)对应的方法为 this.getItems()对应的方法为 在getItems( ...
- 关于.Net Core使用Elasticsearch(俗称ES)、Kibana的研究说明
关于ElasticSearch Elasticsearch是一个分布式的开源搜索和分析引擎,适用于所有类型的数据,包括文本.数字.地理空间.结构化和非结构化数据.Elasticsearch 在 Apa ...
- Linux中su和sudo的用法
su -#su - oldboy //当执行这个命令的时候表示切换到oldboy用户,并且重新读取用户环境相关配置文件,具体的来说就是执行下用户家目录下.bash_profile和.bashrc文件, ...
- 第3章:快速部署一个Kubernetes集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点$ kubeadm in ...
- Docker:如何修改Docker0网桥的默认网段
1. 背景 Docker 服务启动后默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络. ...
- Linux导出未越狱Iphone10.3-QQ聊天记录
起因 手机当中的聊天记录已经快两年没有备份了,生怕某天QQ版本升级中丢失掉这些聊天记录,所想将这两年的聊天记录保存下来 查找了好多资料,结果10.3以后,IOS改变了策略,貌似不允许通过以前方法导出了 ...
- bugKu管理员系统
先F12看看,有啥发现的,发现一段注释... 感谢那个群友分享了怎么辨别base64编码,通常是A-Z,a-z,0-9,+,/,=.最后通常有0个到2个等号,我也成功用在线解码器,确实是base64编 ...
- Oracle如何以逗号分隔的字符串拆分为多行数据
近期在工作中遇到某表某字段是可扩展数据内容,信息以逗号分隔生成的,现需求要根据此字段数据在其它表查询相关的内容展现出来,第一想法是切割数据,以逗号作为切割符,以下为总结的实现方法,以供大家参考.指教. ...