`
xieyj
  • 浏览: 102711 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

System.gc初步分析

阅读更多

     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);
            }

 }

 堆栈里面存着基本类型及引用类型,它们的位置及垃圾回收算法是如何区分这些类型的,这个还需要进一步的分析。

5
0
分享到:
评论

相关推荐

    system.new.dat.br和system.new.dat解包工具

    在Android系统中,"system.new.dat.br" 和 "system.new.dat" 文件是刷机过程中常见的文件格式,尤其在MIUI等定制系统中尤为常见。这些文件通常包含系统的核心组件和应用,是Android设备升级或恢复时的重要部分。本文...

    System.Web.Extensions.dll

    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. 系统找不到指定的文件。 ...

    AndroidRom之system.img内容提取工具

    可用附件中的simg2img.exe来转化一下原始的system.img,然后再用其中的ext2Explorer来浏览提取system.img中的内容。 用法:1、将system.img改名为system.img.ext4。2、命令行cd到simg2img.exe目录下,执行命令“simg...

    system.new.dat.br相互转换system.new.dat工具

    现在的第三方安卓8.1rom里面的system.new.dat.br,怎么转成原来的system.new.dat 2015年9月, Google就已经在官方博客上发布了新的压缩算法Brotli, 并开源在了Github上.同时还发布了一个研究报告, 対Brotli, ...

    System.Data.SQLite.dll x64,x86多个版本

    System.Data.SQLite.dll是SQLite数据库引擎在.NET Framework环境下的一个组件,它为.NET开发者提供了一种无缝集成SQLite数据库的途径。SQLite是一个开源、轻量级、自包含的关系型数据库管理系统,适用于移动设备和...

    System.web.dll下载

    《深入理解System.web.dll及其在ASP.NET MVC中的应用》 System.web.dll是.NET Framework的核心组件之一,主要用于构建基于ASP.NET的Web应用程序。这个动态链接库(DLL)包含了大量与Web开发相关的类和方法,使得...

    system.new.dat与system.new.dat.br一键互相转换工具

    支持system.new.dat与system.new.dat.br互相转换功能,同样也支持vendor.new.dat与vendor.new.dat.br互相转换,操作十分简单,只需一键就能转换。也支持img与dat一键互换,安卓全版本适配。

    SYSTEM.NEW.DAT解包工具(可解5.0-8.0系统)

    在Android系统中,`SYSTEM.NEW.DAT`是一个重要的系统文件,它包含了系统的各种核心组件、设置和应用程序。这个文件通常是经过打包处理的,以便于在设备上高效地存储和分发。本文将深入探讨`SYSTEM.NEW.DAT`的结构、...

    System.Data.SQLite.dll各版本

    System.Data.SQLite.dll是SQLite数据库引擎在.NET环境中的一个封装库,它使得.NET开发者可以方便地在应用程序中使用SQLite数据库。SQLite是一款开源、轻量级、自包含的SQL数据库引擎,适用于各种规模的应用程序,...

    unity 可以使用的System.Drawing.dll

    然而,有时候开发者可能需要更高级的图像处理功能,比如像素操作、图像格式转换或图像分析等,这时就可能需要用到.NET框架中的System.Drawing.dll库。 System.Drawing.dll是.NET Framework的一部分,它提供了一系列...

    使用System.IO.Ports读取COM口数据

    使用System.IO.Ports命名空间可以轻松地实现串口通信。 在C#中,System.IO.Ports命名空间提供了SerialPort类,该类用于控制和管理串行通信端口。SerialPort类提供了多种属性和方法,用于配置串口、发送和接收数据。...

    System.Data.Entity

    《深入理解System.Data.Entity》 System.Data.Entity是.NET框架中一个关键的部分,它构成了Entity Framework的核心,这是一个强大的对象关系映射(ORM)框架,用于简化数据库操作。ORM允许开发人员使用面向对象的...

    System.Data.SQLite.dll(sqlite_1.0.76.0.zip)

    System.Data.SQLite.dll是SQLite在.NET平台上的一个封装库,它为C#和其他.NET语言提供了对SQLite数据库引擎的全面支持。SQLite是一款轻量级、自包含的数据库系统,广泛应用于嵌入式系统和移动应用,因为它不需要单独...

    System.Windows.Interactivity.dll Version 4.5.0.0

    System.Windows.Interactivity.dll是Microsoft Prism框架的一个重要组件,版本号为4.5.0.0。Prism是一个用于构建WPF(Windows Presentation Foundation)和UWP(Universal Windows Platform)应用程序的开源库,它...

    System.Web.Http.zip

    标题 "System.Web.Http.zip" 指示了一个与Web开发相关的压缩文件,其中包含了用于处理HTTP请求的DLL(动态链接库)文件。这个文件可能是针对.NET Framework开发的,因为System.Web.Http命名空间是ASP.NET Web API的...

    System.Windows.Forms.DataVisualization.dll 3.5 版本

    使用System.Windows.Forms.DataVisualization.dll,开发者可以方便地创建交互式的图表,使得数据以图形化的方式呈现,提高用户的理解和分析能力。它支持自定义图表的各种属性,如颜色、样式、数据源、图表区、轴标签...

    System.Data.SQLite.1.0.111.rar

    ADO.NET Data Provider for SQLite(-&gt;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 让.net2.0也可以使用Linq

    《System.Linq.dll:让.NET 2.0框架焕发新生》 在.NET框架的世界里,LINQ(Language Integrated Query,语言集成查询)是一个革命性的特性,它首次出现在.NET Framework 3.5中,极大地提升了开发人员处理数据的效率...

    解包打包android内核system.img文件所需工具

    然后mkyaffs2image system system.img打包生成新的system.img,替换原来的system.img,并启动模拟器,效果图如下: 修改代码: 工具:odextools(参考:《一键odex批量合并工具odextools的重新整理与使用...

Global site tag (gtag.js) - Google Analytics