当前位置:首页 > 嵌入式 > 嵌入式硬件
[导读] Java[1]语言为字符串操作提供了丰富的支持,它将字符串封装在三个类中并提供多种字符串操作接口。在Java应用程序中,由于对字符串的使用量比较高,从而使得其需要消耗较大的堆空间。例如在J2EE应用

Java[1]语言为字符串操作提供了丰富的支持,它将字符串封装在三个类中并提供多种字符串操作接口。在Java应用程序中,由于对字符串的使用量比较高,从而使得其需要消耗较大的堆空间。例如在J2EE应用服务器运行过程中,约40%的活跃堆空间被用来保存字符串数据[2]。

通过对Java中字符串操作接口的分析可以发现,随着这些操作的运行会产生较多的无用字符串,它们不再被Java类封装并且也不被任何变量引用。这些无用字符串数据将一直停留在活跃堆中,直到Java虚拟机启动垃圾收集将其回收。而由于字符串数据具有单个对象占用空间较小但总体数量很大的特征,大量的无用字符串数据不仅会影响堆空间的利用率,并且对Java虚拟机垃圾收集的性能有较大影响。

当前对Java中字符串的内存管理优化方案主要关注于字符串的使用效率上,如消除常量重复、延迟分配等技术[2],通过修改Java虚拟机对字符串分配回收的支持来提高堆中字符串的使用效率。然而这些方案无法处理堆中已经成为无用字符串的数据,只能等待垃圾收集来处理。

近期编译时的独立对象回收策略[3]则专注于在编译阶段对应用程序做分析并插入回收指令以回收无用对象空间,但是该方案对Java库函数只做保守分析从而无法回收这些无用字符串。为此,本文从对字符串操作接口的分析出发,识别各类操作对字符串的改变情况以利用独立对象回收策略中的指令插桩技术来主动回收无用字符串对象,以提高堆空间的利用率、减低垃圾回收的负担、改善Java虚拟机的性能。

1 Java中字符串的支持与分析

1.1 Java中字符串的支持

Java语言将字符串的表示和操作都封装在StringBuilder、StringBuffer和String三个类中。其中前两个类指向的字符串是可变的,String类指向的字符串是不变的。这三个类的内部结构基本上一致,以StringBuilder为例,StringBuilder在Java中的结构如图1所示。

从图1可以看出,字符串数据由StringBuilder对象指向的value域保存,在内存空间上反映为两个对象:StringBuilder对象通过value域指向字符串对象。由于该类提供常用的可变字符串操作接口且相对另一个类StringBuffer具有较高的执行效率,对字符串数据的操作在Java虚拟机中一般会将其转换为StringBuilder对象再做处理。下面以一个语句示例来说明这一点:

 String s=new String(‘aa’+’bb’+’cc’);
该语句的语义是将三个字符串连接在一起并生成一个String对象,在Java语言的源程序级别上不会出现StringBuilder对象,但是经过编译器优化之后,这条语句实际被翻译为下面的字节码形式(为简化描述,本文以源语言来表示字节码的操作):
StringBuilder t=new StringBuilder(‘aa’);
t.append(‘bb’);
t.append(‘cc’);
String s=t.toString();

即Java编译器会首先创建一个StringBuilder对象,完成字符串的连接工作之后再将其转变为String对象。由于类似于这种情况的字符串操作较多地出现在输出方法和字符串创建方法中,所以可推断出StringBuilder有着较大的使用频率,故将以其为代表分析其提供的接口对字符串的影响。

1.2 无用字符串的产生

在上节的示例中,StringBuilder类提供的append()接口将会改变value域所指向的字符串,其做法是:新建长度为连接后字符串长度之和的字符数组,分段复制之后使其成为value域指向的新数组,而value域指向的原数组将被丢弃成为无用字符串。

图2为示例语句中append()接口引起的value域指向字符串变化图。

从图2可以看出,在append()接口执行过后,对象的字符数组将指向新建的字符串’aabb’,原有字符串’aa’将不被任何变量指向而成为无用字符串。

由于StringBuilder类的value域指向的字符串是可变的,在其提供的接口中存在大量类似append()可能对value域做出改变的接口,如insert()、replace()等。而在Java虚拟机对这些接口的调用频率较多,表1是基准测试程序Jolden[4]的4个子程序中字符串操作接口调用次数以及可能对value域做出改变的接口调用次数对比。

由表1可以看出,可能对value域做出改变的调用次数占字符串操作接口调用次数的22.6%~45.7%,占有不可忽视的比例。下面将深入分析这些可能改变value域的操作接口的具体实现。

1.3 字符串操作接口分析

可能对value域做出改变的操作接口有一个共同点,即this对象不会发生变化,只是其value域指向一个新建的字符串。对字符串的操作接口做深入分析后可知,在append()等可能改变value域指向的操作接口的实现中,存在两条改变分支:例如在接口append(s)中,如果s为null或者s的value域指向一个空字符串,则该接口不会改变this对象的value域指向;否则才会新建一个字符串以被this对象的value域指向。

可以将这两条改变分支表现为下面的形式:
分支1:不做任何改变。
分支2:新建字符串,使其被this对象的value域指向,原有字符串成为无用字符串。
下面将给出根据本节的分析给出的无用字符串回收方案。

2 字符串的回收方案

对无用字符串的回收存在两个难点:(1)不可深入改变Java的库函数实现。因为回收方案需要具有较强的通用性和灵活性;(2)由于操作接口具体实现中对value域的改变存在分支,并且只能在应用程序的运行阶段判断究竟执行的是哪个分支。

本文采用独立对象显式回收策略中的指令插桩技术来解决上述两个难题:在可能发生改变的字符串操作接口调用点处插入判定语句来对操作接口执行的分支做判断,然后根据结果来实施字符串的回收方案。由于这些语句都插桩在用户程序中,不会改变Java库函数的实现,而且这些语句会随着字符串操作接口的执行而执行,所收集的信息属于运行时信息,故可以很好地判断运行时分支的情况。

由于两条分支的不同之处表现为操作接口执行完毕之后,this对象的value域指向是否发生了变化,故可以采取接口调用前后value域比较的方式来判断具体执行的分支。本文使用指令插桩技术,在Java虚拟机重编译Java字节码时对其做指令插桩工作,其处理流程为:

(1)在Java虚拟机处理应用程序指令时判断其是否为可能引起字符串变化的操作接口调用指令。
(2)如果是则实施步骤(3)~(5)的指令插桩工作。
(3)在调用指令之前插入this对象的value域引用保存指令。
(4)在调用指令之后插入this对象的value域引用保存指令。
(5)安插两个引用的对比指令,如果不同,则插入回收指令以回收调用之前保存的引用;否则将不做处理。

本方案用到了独立对象回收技术中的回收指令,需要在Java虚拟机的内存管理模块支持这个回收指令。由于对回收指令的支持对原有的分配和回收方案影响很小,故其实现较简单并且具有一定的通用性。

以图3为例来说明本文的字符串回收方案。由于该方案处理的为Java字节码,为了方便理解,将以实际代码的形式体现:由图3可看出,在调用点前后加入了value域引用保存指令记录了调用点执行前后的value域的引用信息,然后将两者做对比处理来判断调用点是否对value域的引用做出了改变,如果引用信息有了变化,则之前的value域引用成为了无用字符串,可以插入回收指令将其回收。

可以将该无用字符串回收方案应用到其他可能对对象内部value域指向的字符串做出改变的接口调用点,即可以在运行时回收由这些接口运行而出现的无用字符串数据。

3 实验结果及分析

在Apache的开源Java SE(Standard Edition)平台Harmony[5]上实现了针对字符串的回收方案,并做了相关的实验测试。测试平台的操作系统是Windows 7 Ultimate,CPU为Intel Pentium Dual E2200,主频为2.2 GHz,内存为2 GB。测试用例为Jolden中的4个基准程序。

在实现了无用字符串的显式回收之后,可以在运行中主动回收一些无用字符串以提高活跃堆空间的利用率和降低Java虚拟机垃圾回收的开销。表2给出了主动回收的无用字符串大小和总分配大小的比较情况。

由表2可以看出,本文的回收方案主动回收的无用字符串占应用程序总分配空间的5%~18%,对堆空间的利用率有较大的提升。对无用字符串的主动回收也带来了Java虚拟机的性能提升,因为可以减轻垃圾收集的负担。表3给出了实现无用字符串回收方案前后测试程序在Java虚拟机中的执行时间对比。

 由表3可以看出,经过对无用字符串的主动回收处理,Java虚拟机对应用程序的执行效率也有了改善,分别减少了1%~5%。这说明无用字符串的回收可以提升Java虚拟机的性能。

本文提出一种对Java应用程序中无用字符串进行显式回收的方案,以指令插桩的形式收集应用程序运行时信息并主动回收堆中无用字符串,以提高堆空间的利用率。实验结果表明,该方案可以有效提高Java虚拟机的性能和Java应用程序的执行效率。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

上海2023年9月20日 /美通社/ -- 2023年9月19日-23日,第二十三届中国国际工业博览会(以下简称“工博会”)在国家会展中心(上海)举行,来自全球30个国家和地区的2800家展商,覆盖从基础材料、基础零部件...

关键字: 富士 存储技术 IBM 数据流

Python和Java是两种广泛应用于编程领域的高级编程语言,它们各有优劣。本文从程序设计应用、系统资源占用、高性能处理和语言特点等四方面详细介绍两种编程语言的区别。

关键字: python java 高性能处理

在这篇文章中,小编将为大家带来Java接口的相关报道。如果你对本文即将要讲解的内容存在一定兴趣,不妨继续往下阅读哦。

关键字: java 接口 Interface

上海2022年12月16日 /美通社/ -- 近期,涅槃汽车发表了一篇文章,对智能座舱数据存储技术进行解析,内容如下: 1、 智能座舱的存储越来越重要,容量越大越大。 我们都知道,中国新能源汽车逐步在迈向正...

关键字: 数据存储 汽车 存储技术 BSP

应该有不少小伙伴有假期打工的经历,那今天就来给公众号的读者朋友们分享一个二哥编程星球里一个球友在富士康打工 50 天的感受,相信大家看完后会深深触动的。

关键字: 物联网 java 博客

北京2022年10月11日 /美通社/ -- 在1992年出版的《雪崩》一书中,作者尼尔·史蒂芬森第一次提出Metaverse(元宇宙)这一概念;斗转星移,三十年之后,随着Roblox上市、Facebook...

关键字: 区块链 存储技术 带宽 分布式

(全球TMT2022年8月4日讯)近日,Gartner公布2022年存储和数据保护技术成熟度曲线(Hype Cycle for Storage and Data Protection Technologies, 202...

关键字: 分布式 存储技术 GARTNER 软件定义

北京2022年4月28日 /美通社/ -- 数据是元宇宙的核心要素,面对元宇宙时代的海量数据爆发,如何实现安全、可靠、高效存储?日前,浪潮信息参与第五期开放计算技术沙龙“元宇宙存储研究与实践”,与来自中国科学技术大学、郑...

关键字: 区块链 云存储 数据中心 存储技术

北京, 2022年4月2日 /美通社/ -- 新一代信息技术正加速数字经济时代的到来,数据作为数字经济时代的信息支撑,数据成为继土地、劳动力、资本、技术之后的第五大生产要素,正在成为驱动经济社会发展的重要力量。 数据也...

关键字: 存储技术 AI

双方将推动分区存储技术标准化,共同致力于开发和推广硬件规范,以及软件应用模型,以建立一个强大的生态系统 深圳2022年3月30日 /美通社/ -- 三星和西部数据(Nasdaq: WDC)于今日宣布,双方已签署一份独特...

关键字: 三星 存储技术 西部数据
关闭
关闭