Javap查看Class指令
javac Hello.java
- public class Hello{
- static int num = 1;
- void hello(){
- String s = "aa";
- System.out.println(s);
- String s2 = new String("aa");
- System.out.println(s2);
- }
- }
javap -v Hello.class
- Classfile /G:/workspace/Projects/Golang/Hello.class
- Last modified 2014-12-30; size 527 bytes
- MD5 checksum e84276bb63ef1ea05d80fa07852dfce2
- Compiled from "Hello.java"
- public class Hello
- SourceFile: "Hello.java"
- minor version: 0
- major version: 51
- flags: ACC_PUBLIC, ACC_SUPER
- Constant pool:
- #1 = Methodref #9.#20 // java/lang/Object."<init>":()V
- #2 = String #21 // aa
- #3 = Fieldref #22.#23 // java/lang/System.out:Ljava/io/PrintStream;
- #4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V
- #5 = Class #26 // java/lang/String
- #6 = Methodref #5.#27 // java/lang/String."<init>":(Ljava/lang/String;)V
- #7 = Fieldref #8.#28 // Hello.num:I
- #8 = Class #29 // Hello
- #9 = Class #30 // java/lang/Object
- #10 = Utf8 num
- #11 = Utf8 I
- #12 = Utf8 <init>
- #13 = Utf8 ()V
- #14 = Utf8 Code
- #15 = Utf8 LineNumberTable
- #16 = Utf8 hello
- #17 = Utf8 <clinit>
- #18 = Utf8 SourceFile
- #19 = Utf8 Hello.java
- #20 = NameAndType #12:#13 // "<init>":()V
- #21 = Utf8 aa
- #22 = Class #31 // java/lang/System
- #23 = NameAndType #32:#33 // out:Ljava/io/PrintStream;
- #24 = Class #34 // java/io/PrintStream
- #25 = NameAndType #35:#36 // println:(Ljava/lang/String;)V
- #26 = Utf8 java/lang/String
- #27 = NameAndType #12:#36 // "<init>":(Ljava/lang/String;)V
- #28 = NameAndType #10:#11 // num:I
- #29 = Utf8 Hello
- #30 = Utf8 java/lang/Object
- #31 = Utf8 java/lang/System
- #32 = Utf8 out
- #33 = Utf8 Ljava/io/PrintStream;
- #34 = Utf8 java/io/PrintStream
- #35 = Utf8 println
- #36 = Utf8 (Ljava/lang/String;)V
- {
- static int num;
- flags: ACC_STATIC
- public Hello();
- flags: ACC_PUBLIC
- Code:
- stack=1, locals=1, args_size=1
- 0: aload_0
- 1: invokespecial #1 // Method java/lang/Object."<init>":()V
- 4: return
- LineNumberTable:
- line 1: 0
- void hello();
- flags:
- Code:
- stack=3, locals=3, args_size=1
- 0: ldc #2 // String aa
- 2: astore_1
- 3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
- 6: aload_1
- 7: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
- 10: new #5 // class java/lang/String
- 13: dup
- 14: ldc #2 // String aa
- 16: invokespecial #6 // Method java/lang/String."<init>":(Ljava/lang/String;)V
- 19: astore_2
- 20: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
- 23: aload_2
- 24: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
- 27: return
- LineNumberTable:
- line 4: 0
- line 5: 3
- line 6: 10
- line 7: 20
- line 8: 27
- static {};
- flags: ACC_STATIC
- Code:
- stack=1, locals=0, args_size=0
- 0: iconst_1
- 1: putstatic #7 // Field num:I
- 4: return
- LineNumberTable:
- line 2: 0
- }
static {};静态初始化代码;
String s = "aa";和new String("aa");从同一常量池出获取值
Java的8中基本类型:boolen,char,byte,short,int,long,float,double,基本类型的值被存储在栈中,因为这样更快。
栈:
1、当定义 int a = 10 时,编译器会在栈中分配4个字节空间来存放值(10),内存地址(0x0001)。
2、创建变量a, a的内存地址(0x0005),存放(10)的地址(0x0001)。引用(10)。
3、再定义 int b = 10 时,b的内存地址(0x0006), 同样存放(10)的地址(0x0001)。引用(10)。
所以栈中的数据是共享的。
堆:
内存池,存储所有使用new出来的Java对象。
创建一个对象通常包括两个步骤:
1、对象声明(即创建对象引用)。
2、实例化(即为对象在堆中分配存储空间)。
常量
堆,方法区,栈和本地方法栈
堆(-Xms和-Xmx)调节
new出来的对象实例,都在堆上分配内存。
方法区(-XX:PermSize和-XX:MaxPermSize)调节
存放:类、静态变量和常量。
静态变量、常量、类太多,永久带内存可能不够。
栈和本地方法栈(-Xss)调节
存放:局部变量、参数、操作,方法出口等与方法相关的信息。
方法调用层次太多(递归), 该区内存可能不够。
===============================================================
(heap, stack, data-seg, code-seg)
heap:-->new出来对象。
stack:--局部变量,用来计算的。
data-seg:-->静态变量、字符串常量
code-seg:-->代码
===============================================================
public void print(){
Object o = new Object();
}
这里这里程序会创建两个对象内存空间:
1、new Object()存在堆中。
2、o引用,存在栈中。
堆中的内存是由GC来管理回收的。(程序中没有对该对象存在引用)
栈中的内存是当方法的栈帧运行完后就释放的(引用占4个字节)。
程序运行时涉及:(指令栈,本地变量区、操作数区)
public void print(){
Integer l;
for (int i=1; i < 3; i++) {
l = 2;
}
}
与
public void print(){
for (int i=1; i < 3; i++) {
Integer l = 2;
}
}
后者Integer l 在同一goto指令内,栈对象都是复用的,刻意写成前者,对内存优化并没有任何实在意义。
用来o后设置 为o=null。
在同一方法栈内,o为局部变量,且为引用类型,对内存优化并没有任何实在意义。