Java 虚拟机在运行 Java 应用程序的查询操作时,存在由于查询结果数据量大和查询并发性高而出现系统不稳定的问题。提出了一种 JVM 内存使用优化方案:恒定使用 JVM 内存,能够在不提高硬件成本的情况下,保证系统连续稳定地运行。
目录
1 引言
2 JVM 内存使用未优化出现的问题
2.1 当机的出现
2.2 对出现当机问题的分析
3 JVM 内存使用优化方案
3.1 优化思路
3.2 生成查询结果文件
3.3 查询结果的读取
4 结束语
5 总结与展望
1 引言
基于 Java 的应用程序实际运行过程中,因为其语言自身所具备的特点以及虚拟机等方面的影响,其相应客户端硬件配置的实际要求要比VC++和VB语言编写的程序高出许多。尽管Java 2对于JDK虚拟机解释器实施了优化处理,但并不能够达到是用户的某些要求。所以,Java程序的开发人员在对程序代码优化过程中,比较注重它的运行性能。其实,Java 运行程序能够从依靠其他方面进行相应的优化,即对程序所占用内存空间进行管理优化。很多功能复杂的Java应用程序在运行时因为系统频繁针对内存进行存储文件操作,所以极大的降低了软件实际运行性能。程序中存在的内存漏洞造成了程序通过操作系统消耗内存,而没有及时进行对内存空间的复用和释放,致使程序消耗相应的内存空间越来越大。
衡量Java程序内存行为的一项重要指标就是内存分配速率,它的含义是指在单位时间内分配给运行程序内存容量。在计算该指标数据时一般情况下不包括收集内存垃圾所占用的时间。一个程序在其运行的时候会连续产生多个对象,这就同时需要有相应的回收垃圾对象的内存垃圾回收程序,而内存垃圾产生的速度快慢也对 Java 程序的内存运行效率有很大的影响。Java程序运行的基本流程是首先分配程序运行所需的内存,当在程序运行过程中出现堆空间不够这种情况时,就会进行垃圾对象的回收。当垃圾对象回收完成后,当前可用内存容量就会恢复到一个数量,这个数量的内存容量是当前正在运行的 Java 程序存储其运行所需的数据结构所需要占用的内容容量,也是其工作时需要占用的基本内容空间,该内存空间可以称为工作内存。工作内存空间数量的变化同时也能够反映出来Java程序运行所需的数据结构所占用的内存容量的变化情况。
尽管现在内存的性价比越来越高,但 OS 管理内存的空间不是无限大的,JVM 对内存的管理能力也是有限的。
由SUN公司提供的JVM内存使用空间资料如表1所示。在硬件配置一定的情况下,如果JVM 能够巧妙的使用有限的内存,则可以使系统避免因内存overflow而出现当机的情况。
因此,对JVM的内存使用优化技术进行研究将具有重要的价值。下面针对在某公司的业务查询中出现的问题进行分析研究,并给出具体的解决方案。
2 JVM 内存使用未优化出现的问题
网络计算机(Network Computer:NC)在教育、电信、保险、金融等行业的市场表现良好,已创造出相当可观的经济效益和社会价值,具有很大的发展潜力。由支持Java的三层构架实现的 NC的软件设计如图1 所示,这种结构已成为 NC 发展的必然趋势2。
NC系统软件包括两大部分:运行在NC上的NCOS和运行在应用服务器上的NC Server。由图1可以看出Java虚拟机(Java Virtual Machine-JVM)是两大部分的主要组件,它对内存的管理能力将影响Java应用程序执行的具体效果以及NC中其他服务的性能表现。
2.1 当机的出现
某公司管理系统采用结构情况:在数据库服务器端使用的是Sybase12.5,应用服务器使用的是Web Logic8,网络操作系统采用的是 Linux。系统起初运行时一切正常,因为该公司是一家省级公司,在各地市都有分支机构,所以随着业务量的增加,数据库也越来越大。在一次月终总结查询时,需要查询结果记录量很大,这时出现了服务器停止响应的当机故障。
2.2 对出现当机问题的分析
Java程序在运行时处理内存短缺问题方面的解决方案通常是使用Java语言提供的无用内存单元回收功能(又称为垃圾回收功能。程序在运行过程中需要构造对象实例,这时程序解释器向操作系统发出内存申请,操作系统从内存堆中预留一块内存空间,并使用这个空间来存储对象实例变量的值。在程序运行过程中对象、变量和方法的构造都会占用一定的内存空间。而某些变量或对象在完成了一次或几次调用后不会继续被程序所使用。“无用单元回收”这一概念的含义就是程序中一个实用线程或进程跟踪程序,对那些不再被使用的内存单元进行清理,并将释放后的内存单元归还操作系统或程序以便复用。但是此进程跟踪程序只有其内存不足时,才开始对“无用单元”实施回收。倘若其内存存在着大量的数据,但其“无用单元”得不到一定的释放时,则会导致内存不足的现象发生。进而致使系统在工作时意外中断等一系列情况产生。
对于上面出现的问题,我们作了这样的研究分析:
①由于查询结果的记录首先要读入 JVM 内存,所以一个查询操作就有可能有大量的数据占用了JVM内存。
②在月终按分类进行金额的汇总时,在各个分支机构点都有这样的操作,此时查询操作的并发性高。大量的查询结果记录同时占用JVM所管理的内存。排除其它硬件问题,出现系统中断情况的一种可能是 JVM 使用的内存不足。
3 JVM 内存使用优化方案
系统在查询结果数据量小且并发查询少的情况下,系统运行是稳定的;只有当数据库中记录总数增多,查询的结果也越来越庞大时,才会出现上面见到的现象。所以,如果各个进程合理使用JVM 内存,而不是长时间大量占用内存,可以解决由内存短缺而造成的系统中断问题4。
依据以上对JVM使用内存的分析,提出解决此问题的一种方案:恒定使用Java虚拟机内存。
3.1 优化思路
恒定使用Java虚拟机内存方案的优化思路是:客户端借由应用服务器进而查询所对应的数据库时,并不是把其所查出的数据记录一次性读入 JVM 内存,进而再返回客户端,实际上是将所查询出来的结果组织为查询结果文件,先将其暂存于应用服务器相应硬盘上,然后将压缩的“查询结果文件”传送到客户端。
3.2 生成查询结果文件
将从数据库所查得出的所有数据,组织为一个查询结果文件,其实际操作如下:每次从数据库服务器读取MAX行(该数据是一个试验值,具体值依赖于应用服务器性能配置和并发访问量) 数据后,在JVM 内存中经过简单加工,写入“查询结果文件”,直至得出全部的结果。所得出的查询结果文件是以压缩形式发出的,可以使其文件变小,进而有效减少客户端读取此文件时的所实际消耗的时间。总而言之,最多只有MAX行的记录占用JVM内存,而其它已查到的记录陆续写入了硬盘,这就保证了JVM内存使用的大小是“恒定”的。对于暂存于硬盘上的压缩文件可以设置定期删除,避免占用大量应用服务器硬盘空间
该步骤主要完成的工作流程:每次首先从数据库查询记录行数的最大值,建立与数据库的连接,执行相应的SQL 查询语句,形成查询 RS 结果集合。从数据库服务器查询数据,并将查询结果形成压缩文件。打开压缩文件输出流,从RS中读取数据,缓存到buffer内存对象,根据需要对数据进行处理,当数量达到预定的阀值时,写入压缩文件,释放内存,同时将计数器清零。向客户端返回查询结果文件的地址,输出剩余数据,最后关闭数据库文件。
3.3 查询结果的读取
暂存于应用服务器上查询结果压缩文件,可直接通过http协议传输给客户端,在客户端仅仅需要将压缩文件进行解压操作,就能够得到所需结果。流程包括:首先从从应用服务器端查询获取结果压缩文件到客户端,然后在客户端完成压缩文件的解压缩,并将结果数据展示出来。
4 结束语
提出的优化方案主要有以下3个特点:
①每次从数据库服务器读取预定的数据行到JVM进行数据加工,然后写入文件系统,从而避免了由于数据量太大而导致JVM内存急剧消耗。
②生成的查询结果文件通过压缩文件的方式传给客户,减小了文件大小,缩短了文件传输时间。
③在系统硬件资源开销不增加的情况下,保证了大数据量查询时系统的稳定性。
优化方案经过实际应用,被证明是一种解决由 JVM内存短缺引起系统不稳定的切实可行的方法。
5 总结与展望
由于传统的Java无法应用在实时领域,本文通过对Java虚拟机的结构改进及功能添加,使得Java虚拟机的实时性有所提高。本文着重与对Java虚拟机本身机制的探讨,发现Java虚拟机中对实时影响的不足,从而针对此不足之处,提出改进。
本文的研究内容主要如下:
1.深入研究Java虚拟机SableVM的体系结构,尤其是其内存管理机制。
2.探讨实时Java虚拟机及其内存管理机制的实现原理。
3.对普通的Java虚拟机SableVM进行实时性改进。着重对内存管理的实时性改进,对其他机制进行辅助性改进,最后对实时内存管理的性能进行实验,得出实验结果。
本文的后续研究工作如下:
Java语言由于其众多的优越性,被用在了很多方面。但是由于它对实时的关注不够,以至于现在还是不能被应用于实时系统,所以增强Java虚拟机的实时性变成了一个亟待解决的新问题。本文虽然提出了一些提高Java虚拟机实时性的方法,但是仅仅改进了内存管理的方面,而RTSJ规定的其他方面的实时性改造并没有涉及到。
在内存管理方面,下一步的工作主要是改进内存分配算法,提高效率。同时由于在执行 Java 的 new 方法时,有可能会引起动态的类装载,而导致分配时间的不确定性,因此可以考虑一种提前装载的策略,使之在分配内存之前就把需要的类装载好。