- 浏览: 103062 次
- 性别:
- 来自: 武汉
最新评论
-
hatedance:
这个bytecodeInterpreter应该已经被遗弃了,现 ...
openjdk中的同步代码 -
Mr_lee_2012:
是啊,好文章,谢过。
java栈帧中的对象引用 -
ZangXT:
有些性能要求比较高的系统会考虑这一点的,典型的如JPC,尽量避 ...
java中调用接口及调用继承类效率区别 -
tinywind:
你有没有注意到load_classfile开始定义了个Reso ...
hotsphot中的ResourceArea -
qianli-2010:
java中调用接口及调用继承类效率区别
openjdk中的垃圾回收是一个庞大的课题,如何标记活动的对象,就涉及到了堆栈的、常量池的跟踪标记等,非常复杂。在此先做一个初步的分析。
先从System.java中的gc方法开始阅读。
public static void gc() {
Runtime.getRuntime().gc();
}
跟踪进去,其实调用到了jvm.cpp里面的JVM_GC(void)
{
if (!DisableExplicitGC) { //如果可以直接进行垃圾回收,则执行下面的一步, -XX:+DisableExplicitGC 选项可以关闭jvm的直接垃圾回收
Universe::heap()->collect(GCCause::_java_lang_system_gc);
}
}
垃圾回收的方式有多种,下面跟踪并发收集(ParallelScavengeHeap.cpp)。
void ParallelScavengeHeap::collect(GCCause::Cause cause) {
...........
VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause);
VMThread::execute(&op);
}
上面的exceute()方法,主要执行的是VM_ParallelGCSystemGC 的doit()方法,下面看看
void VM_ParallelGCSystemGC::doit() {
//在这主要看一下全部回收的代码
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
heap->invoke_full_gc(false);
}
下面是invoke_full_gc代码
inline void ParallelScavengeHeap::invoke_full_gc(bool maximum_compaction)
{
.......
PSMarkSweep::invoke(maximum_compaction);//从名字看出这个方法主要做标记、清除操作
}
跟踪进入上面方法
void PSMarkSweep::invoke(bool maximum_heap_compaction) {
.........
PSMarkSweep::invoke_no_policy(maximum_heap_compaction);
}
上面invoke_no_policy非常复杂,在这仅对其第一阶段的操作进行简单分析。
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
.........
//从根开始对强引用开始进行标记操作
Universe::oops_do(mark_and_push_closure());
ReferenceProcessor::oops_do(mark_and_push_closure());
JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
//跟踪每个线程堆栈,对堆栈里面的对象引用进行跟踪
Threads::oops_do(mark_and_push_closure());
ObjectSynchronizer::oops_do(mark_and_push_closure());
FlatProfiler::oops_do(mark_and_push_closure());
Management::oops_do(mark_and_push_closure());
JvmtiExport::oops_do(mark_and_push_closure());
//跟踪常量池用到的每个类
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
vmSymbols::oops_do(mark_and_push_closure());
}
简单提一下,上面用到的MarkAndPushClosure,它其实就是将对象打上标志,并将对象指针压入一个栈中。采用的是回调函数用法,由上面的oops_do调用。代码如下
{
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (!obj->mark()->is_marked()) {
mark_object(obj); //对遍历到的对象进行标志
_marking_stack->push(obj); //对象入栈
}
}
}
好,回到前面,简单分析一下Threads::oops_do(mark_and_push_closure())。
void Threads::oops_do(OopClosure* f) {
for (JavaThread* p = _thread_list; p; p = X->next()){ //遍历所有用户线程
p->oops_do(f);
}
VMThread::vm_thread()->oops_do(f); //遍历vmThread
}
java对象的方法调用,其在方法内创建的局部变量都在线程堆栈内。javaThread::oops_do应该会对堆栈内的对象进行标记,下面看一下代码。
void JavaThread::oops_do(OopClosure* f) {
Thread::oops_do(f);
........
//下面是堆栈桢的遍历
for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
fst.current()->oops_do(f, fst.register_map());
}
........
}
void Frame::oops_do(OopClosure* f, RegisterMap* map) {
oops_do_internal(f, map, true);
}
void frame::oops_do_internal(OopClosure* f, RegisterMap* map, bool use_interpreter_oop_map_cache) {
if (is_interpreted_frame()) { //以解释桢为例
oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
}
}
void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
............
oops_interpreted_locals_do(f, max_locals, mask);
oops_interpreted_expressions_do(f, signature, is_static,
m->max_stack(),
max_locals, mask);
............
}
void frame::oops_interpreted_locals_do(OopClosure *f,
int max_locals,
InterpreterOopMap *mask) {
for (int i = 0; i < max_locals; i++ ) {
Tag tag = interpreter_frame_local_tag(i);
if (tag == TagReference) { //如果是对象引用,则进行标记,总算找到了
oop* addr = (oop*) interpreter_frame_local_at(i);
assert((intptr_t*)addr >= sp(), "must be inside the frame");
f->do_oop(addr);
}
}
堆栈里面存着基本类型及引用类型,它们的位置及垃圾回收算法是如何区分这些类型的,这个还需要进一步的分析。
发表评论
-
java动态代理
2009-11-19 16:21 933在java里面使用动态 ... -
小议偏向锁
2009-02-02 22:18 2034java SE6采用偏向锁以提高性能。 个人理解,偏向 ... -
java中调用接口及调用继承类效率区别
2009-01-19 22:34 5186都说调用接口要比调 ... -
hotsphot中的ResourceArea
2008-11-09 21:38 1342在ClassLoader::load_cla ... -
athrow程序执行代码
2008-10-10 14:38 1042看看openjdk中的athrow处理流程 { ... -
Object中notify方法
2008-10-08 10:48 2283Object.java类中notify调用的是shar ... -
Object中wait方法
2008-09-18 10:59 3663Object.wait调用 ... -
自定义类加载器loadClass
2008-09-17 15:43 1454自定义类加载器继承ClassLoader类,使用自定义类加载器 ... -
openjdk中的同步代码
2008-09-16 15:24 1825在java虚拟机中的方法同步synchroni ... -
java栈帧中的对象引用
2008-09-12 11:14 3948openjdk中的java栈帧是如何布置的呢, ... -
openjdk的周期线程
2008-09-10 10:04 1328openjdk中周期 ... -
java线程启动代码
2008-09-09 11:24 2004上次写了个《Th ... -
InterpreterRuntime::_new阅读
2008-09-05 14:52 1378InterpreterRuntime::_new为解释 ... -
java解释器的阅读
2008-09-05 10:09 1629前面已经提到了j ... -
JavaCalls::call代码阅读
2008-09-04 10:34 2853JavaCalls::call为hotspot调用j ... -
ClassFileParser::parseClassFile阅读
2008-09-02 11:29 2008instanceKlassHandle ClassF ... -
hotspot中的OO对象分析
2008-08-30 23:03 2194hotspot中的OO对象,涉 ... -
类的加载
2008-08-20 16:00 1288类通过(*env)->FindClass,也就是 ... -
Thread的调用
2008-08-19 11:03 2149在java里面创建线程new Thread().sta ... -
openJdk学习
2008-07-15 11:05 3584学习openJdk,主要 ...
相关推荐
在Android系统中,"system.new.dat.br" 和 "system.new.dat" 文件是刷机过程中常见的文件格式,尤其在MIUI等定制系统中尤为常见。这些文件通常包含系统的核心组件和应用,是Android设备升级或恢复时的重要部分。本文...
Parser Error Message: Could not load file or assembly 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. 系统找不到指定的文件。 ...
可用附件中的simg2img.exe来转化一下原始的system.img,然后再用其中的ext2Explorer来浏览提取system.img中的内容。 用法:1、将system.img改名为system.img.ext4。2、命令行cd到simg2img.exe目录下,执行命令“simg...
现在的第三方安卓8.1rom里面的system.new.dat.br,怎么转成原来的system.new.dat 2015年9月, Google就已经在官方博客上发布了新的压缩算法Brotli, 并开源在了Github上.同时还发布了一个研究报告, 対Brotli, ...
System.Data.SQLite.dll是SQLite数据库引擎在.NET Framework环境下的一个组件,它为.NET开发者提供了一种无缝集成SQLite数据库的途径。SQLite是一个开源、轻量级、自包含的关系型数据库管理系统,适用于移动设备和...
《深入理解System.web.dll及其在ASP.NET MVC中的应用》 System.web.dll是.NET Framework的核心组件之一,主要用于构建基于ASP.NET的Web应用程序。这个动态链接库(DLL)包含了大量与Web开发相关的类和方法,使得...
支持system.new.dat与system.new.dat.br互相转换功能,同样也支持vendor.new.dat与vendor.new.dat.br互相转换,操作十分简单,只需一键就能转换。也支持img与dat一键互换,安卓全版本适配。
在Android系统中,`SYSTEM.NEW.DAT`是一个重要的系统文件,它包含了系统的各种核心组件、设置和应用程序。这个文件通常是经过打包处理的,以便于在设备上高效地存储和分发。本文将深入探讨`SYSTEM.NEW.DAT`的结构、...
System.Data.SQLite.dll是SQLite数据库引擎在.NET环境中的一个封装库,它使得.NET开发者可以方便地在应用程序中使用SQLite数据库。SQLite是一款开源、轻量级、自包含的SQL数据库引擎,适用于各种规模的应用程序,...
然而,有时候开发者可能需要更高级的图像处理功能,比如像素操作、图像格式转换或图像分析等,这时就可能需要用到.NET框架中的System.Drawing.dll库。 System.Drawing.dll是.NET Framework的一部分,它提供了一系列...
使用System.IO.Ports命名空间可以轻松地实现串口通信。 在C#中,System.IO.Ports命名空间提供了SerialPort类,该类用于控制和管理串行通信端口。SerialPort类提供了多种属性和方法,用于配置串口、发送和接收数据。...
《深入理解System.Data.Entity》 System.Data.Entity是.NET框架中一个关键的部分,它构成了Entity Framework的核心,这是一个强大的对象关系映射(ORM)框架,用于简化数据库操作。ORM允许开发人员使用面向对象的...
System.Data.SQLite.dll是SQLite在.NET平台上的一个封装库,它为C#和其他.NET语言提供了对SQLite数据库引擎的全面支持。SQLite是一款轻量级、自包含的数据库系统,广泛应用于嵌入式系统和移动应用,因为它不需要单独...
System.Windows.Interactivity.dll是Microsoft Prism框架的一个重要组件,版本号为4.5.0.0。Prism是一个用于构建WPF(Windows Presentation Foundation)和UWP(Universal Windows Platform)应用程序的开源库,它...
标题 "System.Web.Http.zip" 指示了一个与Web开发相关的压缩文件,其中包含了用于处理HTTP请求的DLL(动态链接库)文件。这个文件可能是针对.NET Framework开发的,因为System.Web.Http命名空间是ASP.NET Web API的...
使用System.Windows.Forms.DataVisualization.dll,开发者可以方便地创建交互式的图表,使得数据以图形化的方式呈现,提高用户的理解和分析能力。它支持自定义图表的各种属性,如颜色、样式、数据源、图表区、轴标签...
ADO.NET Data Provider for SQLite(->net2.0,net4.0,net4.5,net4.51,net4.6,netstandard2.0),System.Data.SQLite.1.0.111.0,System.Data.SQLite.Core.1.0.111.0,System.Data.SQLite.EF6.1.0.111.0,System.Data....
《System.Linq.dll:让.NET 2.0框架焕发新生》 在.NET框架的世界里,LINQ(Language Integrated Query,语言集成查询)是一个革命性的特性,它首次出现在.NET Framework 3.5中,极大地提升了开发人员处理数据的效率...