jclasslib是一个独立的工具,不是包含在JDK中的工具,须要本身进行下载,下载地址以下:java
http://downfile.downcc.com/down/JClassLib_windows.zipwindows
在《Java中的栈》中咱们说到了一个栈帧至少须要包含局部变量表、操做数栈、帧数据区这三个部分。局部变量表是用于保存函数的参数以及局部变量的。顾名思义,局部变量表中的变量只在当前的函数的用中有效,当函数调用结束后,随着函数栈帧的销毁,局部变量表也会随之被销毁。函数
因为局部变量表在栈帧之中,所以,若是函数的参数和局部变量不少,会使得局部变量表膨胀,所以,每一次函数调用,其局部变量表就会占用更多的栈空间,最终致使函数的嵌套调用的次数减小。工具
public class TestStackDeepth { private static int length=0; public static void recursion(long a,long b,long c) { long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=11; length++; recursion(a, b, c); } public static void main(String[] args) { try { recursion(1l,2l,3l); } catch (Throwable ex) { System.out.println(length); } } }
打开jclasslib,选择对应的3中.class文件性能
加载好的jclasslib界面以下图所示优化
在jclasslib中能够看到recursion函数的最大局部变量是26个字。由于该函数一共13个参数和局部spa
变量,并且都是long类型。.net
查看class文件的局部变量表的内容(下图中的局部变量表是指class文件的一个属性,而不是上文中所说的设计
java栈中的每一个栈帧的局部变量表)code
从上面能够看到,在class文件的局部变量表中,显示了每一个变量的做用域范围,所在槽位的索引(index列)、变量名(name列)和数据类型列(J表示long型)。
栈中的局部变量表的槽位是能够重复利用的,若是一个局部变量过了其做用域,那么在其做用域以后申明的新的局部变量颇有可能会复用过时局部变量的槽位,从而达到节省资源的目的。
public class IndexReuse { public static void method1() { int a=0; System.out.println(a); int b=0; } public static void method2() { { int a=0; System.out.println(a); } int b=0; } public static void main(String[] args) { } }
method1中的局部变量表,因为a和b的做用范围都是整个函数,因此,b不用复用a的槽位
method2中的局部变量表,因为a只在{}中起做用,因此b在a以后,能够复用a的槽位,所以a和b的槽位都是0
从上面的例子咱们能够体会到局部变量的声明位置会影响垃圾回收器对变量所占内存空间的回收,所以,在之后的程序设计中,咱们应该尽量的进行优化,从而提升性能。