存储器分配方法、程序和系统的制作方法
【专利摘要】[问题]为了减少创建供Java(R)处理器等使用诸如JNI的预定义接口访问堆外的缓冲区的开销。[解决手段]在本发明中,事先创建被特别称作幻影字节缓冲区的一个或多个字节缓冲区。该幻影字节缓冲区在规范范围内具有尽可能大的大小。设置该幻影字节缓冲区的地址和大小从而覆盖存储器块地址在堆外中的假设范围。当从系统接收到用于利用对地址和大小的指派来创建字节缓冲区的请求时,已经准备好幻影字节缓冲区的程序能够仅通过使用具有相对低开销的字节缓冲区的方法利用所请求的地址和大小对某个幻影字节缓冲区进行切分来创建所请求的字节缓冲区。
【专利说明】存储器分配方法、程序和系统
【技术领域】
[0001]本发明涉及一种计算机存储器分配技术,并且更具体地涉及一种用于Java (R)处理器等的用于在由另一处理器所管理的存储器区域中执行存储器分配的技术。
【背景技术】
[0002]借助于诸如多平台兼容性之类的有利优势,Java (R)目前已经被作为用于构建系统的处理器来使用。
[0003]与此同时,大规模分布式处理系统近年来已经采用了键值存储(KVS)技术。在KVS技术中,许多键值组合使用散列(散列表)而被存储为相关联的阵列。图1示出了以常规方式利用Java (R)所实施的这样的数据结构。在该结构中,KVS中所保存的值被存储为散列表(HashMap) 104,其在实施KVS的服务器系统的Java (R)堆102中包含了多个条目。
[0004]当接收到来自客户端系统的请求时,该服务器系统在堆102中构建字节缓冲区(ByteBuffer)对象106。出于该原因,散列表104中所存储的每条数据的类型是字节缓冲区自身,或者作为字节缓冲区对象的实际数据的字节阵列(byte []),如图1所示。
[0005]然而,以这种方式在堆102上定位许多对象会减少堆中的空间并且导致频繁的垃圾收集。由于垃圾收集的开销连同堆中的对象数量的增加而一起增加,所以运行KVS的JVM中的垃圾收集开销不可避免地变得很高。
[0006]作为针对该问题的解决方案,一种有效的方法是使用如图2所示的机制,其中对象实体位于Java (R)控制以外的存储器区域上(堆外(off heap) 202),并且包含指向条目的锚点(anchor)的指针的堆外表204位于堆102上。在该机制中,在服务器系统从客户端系统接收请求时所创建的字节缓冲区206的对象实体也位于堆外202上。通过如此将对象实体定位于堆外202上,能够减少堆102中的存储器消耗和对象数量,并且还能够减少垃圾收集的开销。
[0007]Java (R)使用被称作Java (R)本地接口(JNI)的机制而利用标准API来处理堆外202中的对象。对于有关JNI的细节,例如参见Rob Gordon的“Essential JN1: JavaNative Interface”,1998, Prentice Hall。
[0008]为了更为具体,调用JNIEnv_>NewDirectByteBuffer(address, size)来创建指向堆外202中之前所分配的存储器块302的字节缓冲区。这里,address是存储器块在堆外中的绝对地址,而size是存储器块的大小。针对有关Java (R)的字节缓冲区的细节,例如参见 Ron Hitchens 的 “Java Nio”,2002, O,Reilly。
[0009]虽然有可能通过调用JNIEnv_>NewDirectByteBuffer(address, size)创建指向在堆外202之前所分配的地址的存储器块302的字节缓冲区,但是所存在的问题在于该创建处理的开销实际上非常高。
[0010]更具体地讲,JNIEnv->NewDirectByteBuffer(address, size)包括以下步骤:
[0011]1.Java (R)利用Java (R)所要求的地址和大小调用JNI库处理器。
[0012]2.JNI 库的(C, C++)处理器执行 JNIEnv_>NewDirectByteBuffer (address, size)。[0013]3.JNI库处理器调用Java (R)处理器,该Java (R)处理器构建并初始化一些Java(R)对象以便创建字节缓冲区。
[0014]4.Java (R)处理器将所创建的字节缓冲区返回至JNI库处理器。
[0015]5.JNI库处理器将所返回的ByteB返回至Java (R)处理器。
[0016]6.Java (R)处理器使用可用的字节缓冲区。
[0017]由于这些步骤的每一个都具有高开销,所以整体开销极高。
[0018]在常规系统中,服务器系统每次接收到来自客户端系统的请求并且需要创建字节缓冲区时,都必须要执行例如以上所提到的高开销的处理JNIEnv->NewDirectByteBuffer (address, size)。这导致了整体性能劣化的问题。
[0019][引用列表]
[0020][非专利文献]
[0021][非专利文献]I:Rob Gordon, “Essential JN1: Java Native Interface,,,1998,PrenticeHall
[0022][非专利文献]2:RonHitchens, “Java Nio”,2002,0,Reilly
【发明内容】
[0023][技术问题]
[0024]本发明的目标是减少创建供Java (R)处理器等使用诸如JNI的预定义接口访问堆外的缓冲区的开销。
[0025][针对问题的解决方案]
[0026]根据本发明,以上问题能够通过事先在规范的范围内创建一个或多个大小尽可能大的字节缓冲区来解决,其在本发明中被特别地称作幻影字节缓冲区。
[0027]在优选实施例中,JNIEnv_>NewDirectByteBuffer(address, size)被类似地调用以创建幻影字节缓冲区,并且该处理自身需要以上所提到的开销。此时,幻影字节缓冲区的地址和大小所指定的范围得以被设置以便覆盖存储器块地址在堆外中的假设范围。然而要注意的是,Java (R) nio的预定义规范将字节缓冲区的大小限制为2GB,并且因此单个字节缓冲区可能不足以覆盖存储器块地址在堆外中的假设范围。
[0028]出于这一原因,优选地,创建不同地址的多个幻影字节缓冲区以便广泛地覆盖存储器块地址在堆外中的假设范围。
[0029]在以上所提到的确保多个幻影字节缓冲区以便广泛覆盖存储器块地址在堆外中的假设范围的情况下,在接收到来自系统的用于创建具有地址和大小的字节缓冲区的请求时,已经准备了幻影字节缓冲区的程序就找出包括该地址和大小所指定的范围的幻影字节缓冲区,并且调用作为字节缓冲区的方法的positionO、IimitO和sliceO。换句话说,所要求地址和大小的字节缓冲区通过以下而被截取:利用所请求地址作为变元调用positionO ;利用所请求大小作为变元调用IimitO ;并且调用sliceO。因此被截取的字节缓冲区可以被用作所指定存储器块在堆外中的缓冲区。当接收到来自系统的用于使用地址和大小所指定的范围创建字节缓冲区的另一个请求时,就重复相同的处理。
[0030]也就是说,一旦创建了幻影字节缓冲区,就能够仅通过利用相对小的开销使用字节缓冲区的方法切分幻影字节缓冲区来创建系统后续所请求的字节缓冲区。[0031]注意到,如果没有包括系统所请求的地址和大小所指定范围的幻影字节缓冲区,则需要利用预定开销创建包括该地址和大小所指定范围的幻影字节缓冲区。然而,这样的处理几乎是不必要的并且在之前根据谨慎预测而创建了幻影字节缓冲区的情况下很少出现。
[0032]此外,如果准备了大量的幻影字节缓冲区,则为了创建每个字节缓冲区可能需要很高开销来识别包括所指定范围的幻影字节缓冲区。然而,这样的开销可以通过删除经常并不包括所请求地址和大小所指定范围的具体幻影字节缓冲区而有所降低。
[0033][发明的有利效果]
[0034]根据本发明,有可能减少创建供Java (R)处理器等使用诸如JNI的预定义接口访问堆外的缓冲区的开销。由于仅通过切开之前所创建的幻影字节缓冲区的一部分而响应于请求来创建缓冲区,该开销得以被降低。
【专利附图】
【附图说明】
[0035]图1是示出堆图的一个示例的示图。
[0036]图2是示出堆外图的一个示例的示图。
[0037]图3是示出堆中的字节缓冲区和堆外中的存储器块之间的对应性的示图。
[0038]图4是示出用于执行本发明的硬件示例的框图。
[0039]图5是示出硬件配置层的示图。
[0040]图6是示出本发明的处理的流程图的示图。
[0041]图7是示出本发明的处理的另一个流程图的示图。
[0042]图8是示出堆中的幻影字节缓冲区和堆外中的存储器块之间的对应性的示图。【具体实施方式】
[0043]随后,将参考附图对本发明的实施例进行描述。应当注意的是,实施例的目的在于描述本发明的优选方法,而并非意在对本发明的范围加以限制。此外,在以下附图中,如果没有另外指出,则相同的标号指示相同的对象。
[0044]图4示出了用于实施本发明实施例的系统配置和处理的计算机硬件的框图。在图4中,连接至系统总线402的有:CPU404、主存储器(RAM) 406、硬盘驱动器(HDD) 408、键盘410、鼠标412和显示器414。CPU404优选地基于32位或64位架构,并且例如可以使用Intel 公司的 Pentium (商标)、Intel 公司的 Core (商标)2Duo、AMD 的 Athlon (商标)等。主存储器406的容量优选地不小于4GB,或者更为优选地不小于8GB。
[0045]操作系统被存储在硬盘驱动器408中。只要其与CPU404相兼容,就可以使用任意的操作系统,诸如Linux (商标)、Microsoft公司的Windows (商标)7、Windows (商标)XP、Windows (商标)2003server 以及 Apple 公司的 Mac OS (商标)。
[0046]诸如Apache的使得系统作为web服务器进行操作的程序也存储在硬盘驱动器408中,并且在系统启动时被加载到主存储器406中。
[0047]用于实施Java (R)虚拟机(VM)的Java (R)运行时环境程序也保存在硬盘驱动器408中,并且在系统启动时被加载到主存储器406中。
[0048]硬盘驱动器408还可以包括JIT编译器,其将字节码应用程序转换为操作系统的本地代码并且运行该程序。
[0049]硬盘驱动器408还在其中存储要被JNI所调用的库,其优选地为以C或C++进行编写并编译的二进制程序。
[0050]键盘410和鼠标412被用来依据操作系统所提供的图形用户界面而对在显示器414上显示的诸如图标、任务栏、文本框等的图形对象进行操作。
[0051]虽然并不局限于此,但是显示器414优选地为具有不低于1024X768分辨率的32位真彩色LCD监视器。例如,显示器414被用来显示实施本发明的程序的启动画面。
[0052]通信接口 416优选地利用以太网(R)协议连接至网络。通过使用Apache所提供的功能,通信接口 416根据诸如TCP/IP之类的通信协议从客户端计算机(未示出)接收处理请求,或者将处理结果返回至客户端计算机(未示出)。
[0053]图5是示出程序或进程的层次的示图。操作系统(OS) 502在图4所示的硬件上运行。Java (R)虚拟机(1]\0 504在03502上运行,并且应用程序506在1]\1504上运行。应用程序506的源代码利用javac等进行编译并且以字节码的形式保存在硬盘驱动器408中。JVM504包括JNI接口及其库,并且本发明的应用程序506使用JNI接口。
[0054]接下来,将参考图6和7所示的流程图对应用程序506所执行的处理进行描述。
[0055]图6中的流程图优选地涉及由应用程序506在其启动时所执行的处理。在步骤602,应用程序506创建一个或多个幻影(phantom)字节缓冲区。特别是在本发明中,幻影字节缓冲区将被称作指向可能包括并不允许JVM对其进行访问的区域的存储器空间的字节缓冲区。这里,address被选择以便覆盖对堆外中的存储器中的存储器块所分配的地址范围。size优选地被设置为2GB,这是能够在java.nio的规范的范围内所能够设置的最大值。用于创建幻影字节缓冲区的处理与随后所描述的图7中所示流程图中的步骤712至720中所示的相同。
[0056]要被单个幻影字节缓冲区所指向的堆外存储器的范围被限制为2GB。因此,如果应用程序506的堆外存储器的假设范围超过2GB,则单个幻影字节缓冲区并不足以覆盖应用程序506的堆外存储器的假设范围。在这种情况下,创建不同地址的多个幻影字节缓冲区以便尽可能多地覆盖应用程序506的堆外存储器的整个假设范围。
[0057]在步骤604,应用程序506优选地将所创建的幻影字节缓冲区的地址和大小的值注册到堆中的预定分区作为诸如散列表的表数据。
[0058]图7中的流程图涉及应用程序506的用于响应于来自系统的请求而创建字节缓冲区的处理。
[0059]步骤702在应用程序506从系统接收到用于创建具体地址和大小的字节缓冲区的请求时被发起。
[0060]随后,在步骤704,应用程序506访问图6的步骤604中所注册的信息,并且搜索包括所指定地址和大小所指示范围的幻影字节缓冲区。
[0061]在步骤706,应用程序506确定是否找到了满足步骤704中所指定条件的幻影字节缓冲区,并且如果是,则根据所指定的地址和大小对找出的幻影字节缓冲区进行划分。字节缓冲区的positionO、limit()和sliceO方法被用于这一操作。更具体地,所要求地址和大小的字节缓冲区通过以下而被截取:利用所请求地址作为变元而调用positionO ;利用所请求大小作为变元而调用IimitO ;并且调用sliceO。因此在步骤710中,被截取的字节缓冲区能够被用作所指定存储器块在堆外中的缓冲区。由此,用于创建字节缓冲区的处理终止。
[0062]返回步骤706,如果没有找到满足步骤704中所指定条件的幻影字节缓冲区,则应用程序506创建自所指定地址开始的范围的幻影字节缓冲区。更确切地讲,在该处理中,应用程序506在步骤712从Java (R)调用JNI。
[0063]随后在步骤714,应用程序506利用所指定的地址和最大大小(2GB)调用JNIEnv->NewDirect 字节缓冲区(address, size)。
[0064]接下来,在步骤716,应用程序506构建用于创建字节缓冲区的一些对象。
[0065]在步骤718,所创建的字节缓冲区被返回至Java (R)0
[0066]随后在步骤720,应用程序506将所创建的字节缓冲区注册为幻影字节缓冲区。
[0067]由此,该处理返回至步骤704。随后,由于新登记了幻影字节缓冲区,所以在步骤704中找到了相对应的幻影字节缓冲区,步骤706中的确定变为肯定,并且在步骤708中通过以以上所提到的方式进行切分而创建字节缓冲区。
[0068]当在步骤706中确定了没有找到具有高开销的幻影字节缓冲区时执行步骤712至720。然而,在大多数情况下,如果幻影字节缓冲区被准备好从而覆盖先前假设范围的存储器地址,则相对应的幻影字节缓冲区都被找到。因此,步骤706中的确定变为肯定并且该过程前进至步骤708,使得开销问题几乎不会出现。
[0069]图8是示出如何切分幻影字节缓冲区并且从其截取实际字节缓冲区的示意性表示形式的示图。在图8中,在图6的步骤602中事先创建了幻影字节缓冲区802。
[0070]随后,如图7的步骤702所示,在从系统接收到用于创建字节缓冲区的请求时,通过在步骤708中对幻影字节缓冲区进行切分来创建实际(即,不同于幻影)字节缓冲区804,并且该实际字节缓冲区804指向堆外中的存储器块808。
[0071]随后,当从系统接收到另一个字节缓冲区创建请求时,通过在步骤708中对幻影字节缓冲区进行切分而创建实际字节缓冲区806,并且该实际字节缓冲区806指向堆外中的存储器块810。
[0072]如已经描述的,一旦以开销为代价创建了幻影字节缓冲区,则随后就能够仅通过对该幻影字节缓冲区进行切分而创建任意数量的所期望的实际字节缓冲区。切分字节缓冲区的处理在Java (R)内完成,这不同于JNI而具有相对低的开销。
[0073]上文中已经以利用JNI创建从Java (R)指向堆外中的存储器块的缓冲区的示例对本发明的实施例进行了描述。然而,应当注意的是,只要处理器包括用于另一系统的本地接口,本发明就并不局限于具体的硬件和操作系统、处理器或应用程序。
[0074][附图标记列表]
[0075]404CPU,406主存储器,408硬盘驱动器,5020S,504JVM,506应用程序,802幻影字节缓冲区,804实际字节缓冲区,806实际字节缓冲区。
【权利要求】
1.一种用于在语言处理器上运行程序的系统的方法,所述语言处理器包括用于访问由绝对地址所指定的存储器空间的缓冲区的特殊类,并且具有通过切开由所述类所指定的所述存储器空间的一部分而创建所述类的功能,所述方法由计算机所实施以创建用于访问所指定存储器空间的所述类的缓冲区,所述方法包括如下步骤: 由所述计算机创建所述类的缓冲区,所述缓冲区是可以包括不允许所述语言处理器进行访问的存储器空间的缓冲区;以及 响应于指派了允许访问的存储器空间和大小,由所述计算机切开创建的所述类的所述缓冲区的一部分,以在所述允许访问的存储器空间中创建所述类的可访问缓冲区。
2.根据权利要求1所述的方法,进一步包括如下步骤:在可能包括不允许所述语言处理器进行访问的区域的存储器空间中创建所述类的多个缓冲区,并且记录所述类的所述缓冲区中每一个的地址和大小。
3.根据权利要求2所述的方法,其中在允许访问的存储器空间中创建所述类的所述可访问缓冲区的所述步骤包括:搜索创建的所述类的其地址被记录的多个缓冲区,以找到包括由指派的地址和大小所指示范围的特定缓冲区,并且切分找到的所述缓冲区。
4.根据权利要求3所述的方法,其中当对找到并切分所述类的包括所述地址的所述特定缓冲区的处理无法找到所述类的包括所述地址的所述特定缓冲区时,所述处理进一步包括用于创建所述类的附加缓冲区的处理,所述附加缓冲区包括存储器空间中不允许所述语言处理器进行访问的地址。
5.根据权利要求1所述的方法,其中在创建所述类的可能包括不允许所述语言处理器进行访问的存储器空 间的所述缓冲区的所述步骤中,以最大的可允许大小来创建所述缓冲区。
6.根据权利要求1所述的方法,其中所述语言处理器是Java(R),所述缓冲区的类是字节缓冲区,用于创建所述类的缓冲区的所述处理通过调用JNI接口来执行,并且通过以下来执行用于切开所述类的所述缓冲区的所述处理:利用PositionO指派起始点,利用IimitO指派大小并且随后调用sliceO方法。
7.一种用于在语言处理器上运行程序的系统的程序,所述语言处理器包括用于访问由绝对地址所指定的存储器空间的缓冲区的特殊类,并且具有通过切开由所述类所指定的所述存储器空间的一部分而创建所述类的功能,所述程序由计算机所实施以创建用于访问所指定存储器空间的所述类的缓冲区,所述程序使计算机执行如下步骤: 创建所述类的缓冲区,所述缓冲区是可以包括不允许所述语言处理器进行访问的存储器空间的缓冲区;以及 响应于指派了允许访问的存储器空间和大小,切开所创建的所述类的所述缓冲区的一部分,以在所述允许访问的存储器空间中创建所述类的可访问缓冲区。
8.根据权利要求7所述的程序,进一步包括如下步骤:在可能包括不允许所述语言处理器进行访问的区域的存储器空间中创建所述类的多个缓冲区,并且记录所述类的所述缓冲区中每一个的地址和大小。
9.根据权利要求8所述的程序,其中在允许访问的存储器空间中创建所述类的所述可访问缓冲区的所述步骤包括:搜索创建的所述类的其地址被记录的多个缓冲区,以找到包括由指派的地址和大小所指示范围的特定缓冲区,并且切分找到的所述缓冲区。
10.根据权利要求9所述的程序,其中当对找到并切分所述类的包括所述地址的所述特定缓冲区的处理无法找到所述类的包括所述地址的所述特定缓冲区时,所述处理进一步包括用于创建所述类的附加缓冲区的处理,所述附加缓冲区包括存储器空间中不允许所述语言处理器进行访问的地址。
11.根据权利要求7所述的程序,其中在创建所述类的可能包括不允许所述语言处理器进行访问的存储器空间的所述缓冲区的所述步骤中,以最大的可允许大小来创建所述缓冲区。
12.根据权利要求7所述的程序,其中所述语言处理器是Java(R),所述缓冲区的类是字节缓冲区,用于创建所述类的缓冲区的所述处理通过调用JNI接口来执行,并且通过以下来执行用于切开所述类的所述缓冲区的所述处理:利用PositionO指派起始点,利用IimitO指派大小并且随后调用sliceO方法。
13.—种在语言处理器上运行程序的系统,所述语言处理器包括用于访问由绝对地址所指定的存储器空间的缓冲区的特殊类,并且具有通过切开由所述类所指定的存储器空间的一部分而创建所述类的功能,所述系统包括: 用于创建所述类的缓冲区的装置,所述缓冲区是可以包括不允许所述语言处理器进行访问的存储器空间的缓冲区;以及 用于响应于指派了允许访问的存储器空间和大小,由所述计算机切开所创建的所述类的所述缓冲区的一部分以在所述允许访问的存储器空间中创建所述类的可访问缓冲区的>J-U ρ?α装直。
14.根据权利要求13`所述的系统,进一步包括如下装置:在可能包括不允许所述语言处理器进行访问的区域的存储器空间中创建所述类的多个缓冲区,并且记录所述类的所述缓冲区中每一个的地址和大小的装置。
15.根据权利要求14所述的系统,其中在允许访问的存储器空间中创建所述类的所述可访问缓冲区的所述装置执行如下处理:搜索创建的所述类的其地址被记录的多个缓冲区,以找到包括由指派的地址和大小所指示范围的特定缓冲区,并且切分找到的所述缓冲区。
16.根据权利要求15所述的系统,其中当对找到并切分所述类的包括所述地址的所述特定缓冲区的处理无法找到所述类的包括所述地址的所述特定缓冲区时,所述处理进一步包括用于创建所述类的附加缓冲区的处理,所述附加缓冲区包括存储器空间中不允许所述语言处理器进行访问的地址。
17.根据权利要求13所述的系统,其中在创建所述类的可能包括不允许所述语言处理器进行访问的存储器空间的所述缓冲区的所述步骤中,以最大的可允许大小来创建所述缓冲区。
18.根据权利要求13所述的系统,其中所述语言处理器是Java(R),所述缓冲区的类是字节缓冲区,用于创建所述类的缓冲区的所述处理通过调用JNI接口来执行,并且通过以下来执行用于切开所述类的所述缓冲区的所述处理:利用PositionO指派起始点,利用IimitQ指派大小并且随后调用sliceO方法。
【文档编号】G06F9/44GK103782273SQ201280043905
【公开日】2014年5月7日 申请日期:2012年7月6日 优先权日:2011年9月9日
【发明者】堀井洋, T·R·吉塞尔 申请人:国际商业机器公司