java变量的存储优化.doc_第1页
java变量的存储优化.doc_第2页
java变量的存储优化.doc_第3页
java变量的存储优化.doc_第4页
java变量的存储优化.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

如果您频繁存取变量,就需要考虑从何处存取这些变量。变量是 static 变量,还是堆栈变量,或者是类的实例变量?变量的存储位置对存取它的代码的性能有明显的影响?例如,请考虑下面这段代码:class StackVarsprivate int instVar;private static int staticVar;/存取堆栈变量void stackAccess(int val)int j=0;for (int i=0; ival; i+)j += 1;/存取类的实例变量void instanceAccess(int val)for (int i=0; ival; i+)instVar += 1;/存取类的 static 变量void staticAccess(int val)for (int i=0; ival; i+)staticVar += 1;这段代码中的每个方法都执行相同的循环,并反复相同的次数。唯一的不同是每个循环使一个不同类型的变量递增。方法 stackAccess 使一个局部堆栈变量递增,instanceAccess 使类的一个实例变量递增,而 staticAccess 使类的一个 static 变量递增。instanceAccess 和 staticAccess 的执行时间基本相同。但是,stackAccess 要快两到三倍。存取堆栈变量如此快是因为,JVM 存取堆栈变量比它存取 static 变量或类的实例变量执行的操作少。请看一下为这三个方法生成的字节码:Method void stackAccess(int)0 iconst_0 /将 0 压入堆栈。1 istore_2 /弹出 0 并将它存储在局部分变量表中索引为 2 的位置 (j)。2 iconst_0 /压入 0。3 istore_3 /弹出 0 并将它存储在局部变量表中索引为 3 的位置 (i)。4 goto 13 /跳至位置 13。7 iinc 2 1 /将存储在索引 2 处的 j 加 1。10 iinc 3 1 /将存储在索引 3 处的 i 加 1。13 iload_3 /压入索引 3 处的值 (i)。14 iload_1 /压入索引 1 处的值 (val)。15 if_icmplt 7 /弹出 i 和 val。如果 i 小于 val,则跳至位置 7。18 return /返回调用方法。Method void instanceAccess(int)0 iconst_0 /将 0 压入堆栈。1 istore_2 /弹出 0 并将它存储在局部变量表中索引为 2 的位置 (i)。2 goto 18 /跳至位置 18。5 aload_0 /压入索引 0 (this)。6 dup /复制堆栈顶的值并将它压入。7 getfield #19 /弹出 this 对象引用并压入 instVar 的值。10 iconst_1 /压入 1。11 iadd /弹出栈顶的两个值,并压入它们的和。12 putfield #19 /弹出栈顶的两个值并将和存储在 instVar 中。15 iinc 2 1 /将存储在索引 2 处的 i 加 1。18 iload_2 /压入索引 2 处的值 (i)。19 iload_1 /压入索引 1 处的值 (val)。20 if_icmplt 5 /弹出 i 和 val。如果 i 小于 val,则跳至位置 5。23 return /返回调用方法。Method void staticAccess(int)0 iconst_0 /将 0 压入堆栈。1 istore_2 /弹出 0 并将它存储在局部变量表中索引为 2 的位置 (i)。2 goto 16 /跳至位置 16。5 getstatic #25 /将常数存储池中 staticVar 的值压入堆栈。8 iconst_1 /压入 1。9 iadd /弹出栈顶的两个值,并压入它们的和。10 putstatic #25 /弹出和的值并将它存储在 staticVar 中。13 iinc 2 1 /将存储在索引 2 处的 i 加 1。16 iload_2 /压入索引 2 处的值 (i)。17 iload_1 /压入索引 1 处的值 (val)。18 if_icmplt 5 /弹出 i 和 val。如果 i 小于 val,则跳至位置 5。21 return /返回调用方法。查看字节码揭示了堆栈变量效率更高的原因。JVM 是一种基于堆栈的虚拟机,因此优化了对堆栈数据的存取和处理。所有局部变量都存储在一个局部变量表中,在 Java 操作数堆栈中进行处理,并可被高效地存取。存取 static 变量和实例变量成本更高,因为 JVM 必须使用代价更高的操作码,并从常数存储池中存取它们。(常数存储池保存一个类型所使用的所有类型、字段和方法的符号引用。)通常,在第一次从常数存储池中访问 static 变量或实例变量以后,JVM 将动态更改字节码以使用效率更高的操作码。尽管有这种优化,堆栈变量的存取仍然更快。考虑到这些事实,就可以重新构建前面的代码,以便通过存取堆栈变量而不是实例变量或static 变量使操作更高效。请考虑修改后的代码:class StackVars/与前面相同.void instanceAccess(int val)int j = instVar;for (int i=0; ival; i+)j += 1;instVar = j;void staticAccess(int val)int j = staticVar;for (int i=0; ival; i+)j += 1;staticVar = j;方法 instanceAccess 和 staticAccess 被修改为将它们的实例变量或 static 变量复制到局部堆栈变量中。当变量的处理完成以后,其值又被复制回实例变量或 static 变量中。这种简单的更改明显提高了 instanceAccess 和 staticAccess 的性能。这三个方法的执行时间现在基本相同,instanceAccess 和 staticAccess 的执行速度只比 stackAccess 的执行速度慢大约 4%。这并不

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论