`

知识收集3【原创】

阅读更多

1.对于韩国人写得jxl的问题(原创工作总结)

    最近用jxl做得模板导出数据出现了严重的性能问题:

        (1)在main方法中运行此业务逻辑时间大约1.662秒,打印时间如图:

      虚拟机运行情况如图:

    

     (2)在Tomcat中运行此业务逻辑时间大约62.182秒,打印时间如图:

     

 虚拟机运行情况如图:

    (3)分析情况

             通过数据和图表认真分析,main方法之所以运行快,因为JVM里面没有大量的垃圾回收,占用的内存又不是很大,jxl进行垃圾回收时,占用的消耗时间不大。

           在tomcat运行中,可以看到JVM里面程序占用的内存比较大,有垃圾存在,每次进行垃圾回收,都会占用大量的时间。

          通过数据分析,main方法的垃圾回收时间很多安基本上忽略不计,而在tomcat里,由于模板总共有47个模板工作表,每个工作表获取数据,要调用3次垃圾回事,每次大约用时0.4秒多,每个工作表用时1.3秒以上,通过计算,大约是60秒以上,可见对整个数据导出占用了大量的时间。

     (4)源码分析

       代码调用处:

             Workbook  wb = Workbook.getWorkbook(file);

             WritableWorkbook wwb = Workbook.createWorkbook(new File(dstFile),wb);

     此程序相当于打开一个文件的副本,进行修改数据,然后回写到源文件

      产生慢的原因:

    产生一个workbook,读取文件

    /**
   * A factory method which takes in an excel file and reads in the contents.
   *
   * @exception IOException
   * @exception BiffException
   * @param file the excel 97 spreadsheet to parse
   * @return a workbook instance
   */
  public static Workbook getWorkbook(java.io.File file)
    throws IOException, BiffException
  {
    return getWorkbook(file, new WorkbookSettings());
  }

 下面这个类的一些参数就是在读取或写入工作簿时用到的(根据一些参数处理)

/**
 * This is a bean which client applications may use to set various advanced
 * workbook properties.  Use of this bean is not mandatory, and its absence
 * will merely result in workbooks being read/written using the default
 * settings
 */
public final class WorkbookSettings

看一下它的构造器:

  /**
   * Default constructor
   */
  public WorkbookSettings()
  {
    initialFileSize = DEFAULT_INITIAL_FILE_SIZE;
    arrayGrowSize = DEFAULT_ARRAY_GROW_SIZE;
    localeFunctionNames = new HashMap();
    excelDisplayLanguage = CountryCode.USA.getCode();
    excelRegionalSettings = CountryCode.UK.getCode();
    refreshAll = false;
    template = false;
    excel9file = false;
    windowProtected = false;
    hideobj = HIDEOBJ_SHOW_ALL;

    // Initialize other properties from the system properties
    try
    {
      boolean suppressWarnings = Boolean.getBoolean("jxl.nowarnings");
      setSuppressWarnings(suppressWarnings);
      drawingsDisabled        = Boolean.getBoolean("jxl.nodrawings");
      namesDisabled           = Boolean.getBoolean("jxl.nonames");
      gcDisabled              = Boolean.getBoolean("jxl.nogc");
      rationalizationDisabled = Boolean.getBoolean("jxl.norat");
      mergedCellCheckingDisabled =
        Boolean.getBoolean("jxl.nomergedcellchecks");
      formulaReferenceAdjustDisabled =
                                Boolean.getBoolean("jxl.noformulaadjust");
      propertySetsDisabled = Boolean.getBoolean("jxl.nopropertysets");
      ignoreBlankCells = Boolean.getBoolean("jxl.ignoreblanks");
      cellValidationDisabled = Boolean.getBoolean("jxl.nocellvalidation");
      autoFilterDisabled = !Boolean.getBoolean("jxl.autofilter");
             // autofilter currently disabled by default
      useTemporaryFileDuringWrite =
        Boolean.getBoolean("jxl.usetemporaryfileduringwrite");
      String tempdir =
        System.getProperty("jxl.temporaryfileduringwritedirectory");

      if (tempdir != null)
      {
        temporaryFileDuringWriteDirectory = new File(tempdir);
      }
     
      encoding = System.getProperty("file.encoding");
    }
    catch (SecurityException e)
    {
      logger.warn("Error accessing system properties.", e);
    }

    // Initialize the locale to the system locale
    try
    {
      if (System.getProperty("jxl.lang")    == null ||
          System.getProperty("jxl.country") == null)
      {
        locale = Locale.getDefault();
      }
      else
      {
        locale = new Locale(System.getProperty("jxl.lang"),
                            System.getProperty("jxl.country"));
      }

      if (System.getProperty("jxl.encoding") != null)
      {
        encoding = System.getProperty("jxl.encoding");
      }
    }
    catch (SecurityException e)
    {
      logger.warn("Error accessing system properties.", e);
      locale = Locale.getDefault();
    }
  }

其中,  gcDisabled = Boolean.getBoolean("jxl.nogc");这个是读取这个是否垃圾回收的参数,默认是false

就是这个这个参数导致读取sheet对象非常的慢,下面会继续进行分析。

 Workbook.createWorkbook(new File(dstFile),wb); 这个方法调用了WorkBook

咱们来进行一些简单的分析:

 /**
   * Creates a writable workbook with the given filename as a copy of
   * the workbook passed in.  Once created, the contents of the writable
   * workbook may be modified
   *
   * @param file the output file for the copy
   * @param in the workbook to copy
   * @return a writable workbook
   * @exception IOException
   */
  public static WritableWorkbook createWorkbook(java.io.File file,
                                                Workbook in)
    throws IOException
  {
    return createWorkbook(file, in, new WorkbookSettings());
  }

这个类相当于产生对Excel修改对象,产生的是一个原文件副本的修改回写

 /**
   * Creates a writable workbook with the given filename as a copy of
   * the workbook passed in.  Once created, the contents of the writable
   * workbook may be modified
   *
   * @param file the output file for the copy
   * @param in the workbook to copy
   * @param ws the configuration for this workbook
   * @return a writable workbook
   */
  public static WritableWorkbook createWorkbook(java.io.File file,
                                                Workbook in,
                                                WorkbookSettings ws)
    throws IOException
  {
    FileOutputStream fos = new FileOutputStream(file);
    WritableWorkbook w = new WritableWorkbookImpl(fos, in, true, ws);
    return w;
  }

此处分析下:WritableWorkbook w = new WritableWorkbookImpl(fos, in, true, ws);中的WritableWorkbookImpl类。

  /**
   * A pseudo copy constructor.  Takes the handles to the font and formatting
   * records
   *
   * @exception IOException
   * @param w the workbook to copy
   * @param os the output stream to write the data to
   * @param cs TRUE if the workbook should close the output stream, FALSE
   * @param ws the configuration for this workbook
   */
  public WritableWorkbookImpl(OutputStream os,
                              Workbook w,
                              boolean cs,
                              WorkbookSettings ws) throws IOException
  {。。。。。。。。。。。。。。。。。。。}

这个构造方法中调用了copyWorkbook(w);,实现了对原Excel文件数据对象的拷贝,相当于一个副本

 /**
   * Produces a writable copy of the workbook passed in by
   * creating copies of each sheet in the specified workbook and adding
   * them to its own record
   *
   * @param w the workbook to copy
   */
  private void copyWorkbook(Workbook w)
  {
    int numSheets = w.getNumberOfSheets();
    wbProtected = w.isProtected();
    Sheet s = null;
    WritableSheetImpl ws = null;
    long start= System.currentTimeMillis();
    for (int i = 0 ; i < numSheets; i++)
    {
      long starts= System.currentTimeMillis();
      s = w.getSheet(i);
      System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"+( System.currentTimeMillis() - starts)/1000.0+" 秒");
      long start3= System.currentTimeMillis();
      ws = (WritableSheetImpl) createSheet(s.getName(),i, false);
      System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+s.getName());
      System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"+( System.currentTimeMillis() - start3)/1000.0+" 秒");
      long start2= System.currentTimeMillis();
      ws.copy(s);
      System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"+( System.currentTimeMillis() - start2)/1000.0+" 秒");
    }
    long start1= System.currentTimeMillis();
 System.out.println("********************************************************************"+(start1 - start)/1000.0+" 秒");
  }

分析下这个影响性能的地方:s = w.getSheet(i);

sheet的实现类是:SheetImpl  (public class SheetImpl implements Sheet)

这个类的构造器:

SheetImpl(File f,
            SSTRecord sst,
            FormattingRecords fr,
            BOFRecord sb,
            BOFRecord wb,
            boolean nf,
            WorkbookParser wp)
    throws BiffException
  {
    excelFile = f;
    sharedStrings = sst;
    formattingRecords = fr;
    sheetBof = sb;
    workbookBof = wb;
    columnInfosArray = new ArrayList();
    sharedFormulas = new ArrayList();
    hyperlinks = new ArrayList();
    rowProperties = new ArrayList(10);
    columnInfosInitialized = false;
    rowRecordsInitialized = false;
    nineteenFour = nf;
    workbook = wp;
    workbookSettings = workbook.getSettings();

}中的workbookSettings = workbook.getSettings();就是WorkBook的参数的传递,里面有垃圾回收的控制参数

看一下WorkBook具体实现类WorkbookParser获取sheet的方法:

 /**
   * Gets the specified sheet within this workbook
   *
   * @param index the zero based index of the required sheet
   * @return The sheet specified by the index
   */
  public Sheet getSheet(int index)
  {
    // First see if the last sheet index is the same as this sheet index.
    // If so, then the same sheet is being re-requested, so simply
    // return it instead of rereading it
    if ((lastSheet != null) && lastSheetIndex == index)
    {
      return lastSheet;
    }

    // Flush out all of the cached data in the last sheet
    if (lastSheet != null)
    {
      lastSheet.clear();
      if (!settings.getGCDisabled())
      {
        System.gc();
      }
    }

    lastSheet = (SheetImpl) sheets.get(index);
    lastSheetIndex = index;
    lastSheet.readSheet();

    return lastSheet;
  }

从此方法中可以看出调用了垃圾回收 if (!settings.getGCDisabled()){
System.gc();
}

  lastSheet.clear();中看下clear方法也调用垃圾回收方法

  final void clear()
  {
    cells = null;
    mergedCells = null;
    columnInfosArray.clear();
    sharedFormulas.clear();
    hyperlinks.clear();
    columnInfosInitialized = false;

    if (!workbookSettings.getGCDisabled())
    {
     
System.gc();
    }
  }

 在readSheet()方法中也调用了垃圾回收方法

  /**
   * Reads in the contents of this sheet
   */
  final void readSheet()

   if (!workbookSettings.getGCDisabled())
    {
      System.gc();
    }

可以源码分析到复制副本,一个sheet总共用了3次垃圾回收,导致时间消耗很大。

为了提高性能,做了如下程序的修改:

     jxl在读取excel的时候,关闭了手工垃圾回收

    System.setProperty("jxl.nogc","true");

或者

     fis = new FileInputStream(file);
   WorkbookSettings wbs = new WorkbookSettings();
      wbs.setGCDisabled(true);
    wb = Workbook.getWorkbook(fis,wbs);
   WorkbookSettings wbss = new WorkbookSettings();
      wbss.setGCDisabled(true);
   wwb = Workbook.createWorkbook(new File(dstFile),wb,wbss);

      垃圾回收器"也许并不像许多人想象的一样会立即执行(当堆中的资源需要释放时),而是在引用类型的引用被删除和它在"堆"中的对象实例被删除中间有个间隔,为什么呢? 因为"垃圾回收器"的调用是比较消耗系统资源,因此不可能经常被调用! (当然,用户代码可以用方法System.GC.Collect()来强制执行"垃圾回收器")

  • 大小: 2.8 KB
  • 大小: 28.9 KB
  • 大小: 33.9 KB
  • 大小: 3 KB
分享到:
评论
1 楼 leo_lnx 2014-03-19  
very good,顶大兵! 

相关推荐

    论文研究 - 钦奈地区高校院士间知识转移的决定因素。

    研究目的:“知识”一词被认为是每个教育机构中最重要的资产,管理知识被认为很难在教育机构中取得成功... 原创性:本文的主要目标是研究位于钦奈地区的工程学院和艺术与科学学院的学术人员之间知识共享的决定性因素。

    2021年高项软考优秀论文范文(十大知识领域各一篇).doc

    二、收集需求 8 三、定义范围 8 四、创建WBS 8 五、确认范围 9 六、控制范围 9 第3篇论信息系统项目的时间管理 11 一、规划进度管理 12 二、活动定义 12 三、排序活动顺序 12 四、估算活动资源 12 五、估算活动持续...

    Tetra-Runner:使用 OpenGL ES 的原创 3D 安卓游戏

    一款使用 OpenGL ES 的原创 3D 安卓游戏。 最初作为犹他大学移动开发课程的最终项目创建,2014 年。首次发布时的总开发时间:53 小时。 这个概念: 我想使用现在已经建立的“跑步者”类型制作一款游戏,这种类型在...

    asp.net知识库

    ASP.NET 2.0 中收集的小功能点 asp.net2.0中的webpart使用小记 2.0问题、错误解决办法 ASP.NET 2.0使用Web Part创建应用程序之二(共二) 体验 .net2.0 的优雅(2) -- ASP.net 主题和皮肤 NET2.0系列介绍(一).NET...

    双机热备的基础知识、配置文档、解决方案及常见问题解决

    本书主要包含了双机热备的基础知识、配置文档、解决方案及常见问题解决。 鉴于工作需要特从WatchStor.com网站收集整理,并加了一部分自己平时整理的 几篇文章,仅供学习参考使用,感谢原创作者们,希望和更多的朋友...

    电感知识及应用.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    电源的分类及知识.zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    单片机 无线电基础知识.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    芯片资料 光电耦合器知识.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    单片机 电源的分类及知识.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    源码 自定义控件 Android自定义控件知识.zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    源码 编程知识 模拟Activity进出栈.zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    电子设计指导 电阻的基础知识.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    电子设计指导 电容的基础知识.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    C 语言最重要的知识点.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    安卓源码 Android自定义控件知识 - 博客园.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    TCPIP相关知识点与面试题集.rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    数据仓库 面试 资料

    数据仓库 面试资料 自己收集 一些知识要点 和体会 原创。

    源码 编程知识 用Roboguice实现依赖注入-.zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。

    网页制作实习报告.doc

    3、巩固运用Fireworks图像处理软件进行网页中图形制作和运用flash动画制作软件设计 网页中动画的知识; 4、巩固综合运用Dreamweaver、Fireworks、flash三个软件完成网站建设任务的方法, 能独立设计一个内容完整、...

Global site tag (gtag.js) - Google Analytics