java,
分享于 点击 36991 次 点评:245
java,
目标:
1、 程序在内存中的经历。
2、 静态类,内部类,静态内部类。在虚拟机里是什么形状的。
3、 变量,常量,静态常量,final静态常量,在虚拟机里是什么样子
4、 锁机制是怎么实现的
虚拟机分为三大系统: 类装载器、 运行时数据区、 执行引擎。
我的问题主要集中在虚拟机运行时数据区这块
第一个问题: 程序的经历
分析这段程序:
public class Test {
public double[] spaceStone = new double[10000];
public static void main(String[] args) throws InterruptedException
{
String s = "1";
List<Test> list = new ArrayList<Test>();
int t1 = 0;
for(;;) {
Test t = new Test();
list.add(t);
System.out.println(" " + t1++);
Thread.sleep(100);
}
}
}
当程序运行时这段代码的类文件将被类加载器加载到 运行时数据区中的方法区
下面汇总一下都是些什么东西存进去了。
javap Test 生成字节码
Compiled from "Test.java"
public class com.myjava.test.Test extends java.lang.Object 1、该类型的全限定名; 2、 直接超类的全限定名; 3、是一个类;4、是public的;
SourceFile: "Test.java"
minor version: 0
major version: 50
Constant pool: // 4、常量池;
const #1 = Method #20.#36; // java/lang/Object."<init>":()V
const #2 = Field #6.#37; // com/myjava/test/Test.spaceStone:[D
const #3 = String #38; // 1
const #4 = class #39; // java/util/ArrayList
const #5 = Method #4.#36; // java/util/ArrayList."<init>":()V
const #6 = class #40; // com/myjava/test/Test
const #7 = Method #6.#36; // com/myjava/test/Test."<init>":()V
const #8 = InterfaceMethod #41.#42; // java/util/List.add:(Ljava/lang/Object;)Z
const #9 = Field #43.#44; // java/lang/System.out:Ljava/io/PrintStream;
const #10 = class #45; // java/lang/StringBuilder
const #11 = Method #10.#36; // java/lang/StringBuilder."<init>":()V
const #12 = String #46; //
const #13 = Method #10.#47; // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
const #14 = Method #10.#48; // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
const #15 = Method #10.#49; // java/lang/StringBuilder.toString:()Ljava/lang/String;
const #16 = Method #50.#51; // java/io/PrintStream.println:(Ljava/lang/String;)V
const #17 = long 100l;
const #19 = Method #52.#53; // java/lang/Thread.sleep:(J)V
const #20 = class #54; // java/lang/Object
const #21 = Asciz spaceStone;
const #22 = Asciz [D;
const #23 = Asciz <init>;
const #24 = Asciz ()V;
const #25 = Asciz Code;
const #26 = Asciz LineNumberTable;
const #27 = Asciz main;
const #28 = Asciz ([Ljava/lang/String;)V;
const #29 = Asciz StackMapTable;
const #30 = class #55; // java/lang/String
const #31 = class #56; // java/util/List
const #32 = Asciz Exceptions;
const #33 = class #57; // java/lang/InterruptedException
const #34 = Asciz SourceFile;
const #35 = Asciz Test.java;
const #36 = NameAndType #23:#24;// "<init>":()V
const #37 = NameAndType #21:#22;// spaceStone:[D
const #38 = Asciz 1;
const #39 = Asciz java/util/ArrayList;
const #40 = Asciz com/myjava/test/Test;
const #41 = class #56; // java/util/List
const #42 = NameAndType #58:#59;// add:(Ljava/lang/Object;)Z
const #43 = class #60; // java/lang/System
const #44 = NameAndType #61:#62;// out:Ljava/io/PrintStream;
const #45 = Asciz java/lang/StringBuilder;
const #46 = Asciz ;
const #47 = NameAndType #63:#64;// append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
const #48 = NameAndType #63:#65;// append:(I)Ljava/lang/StringBuilder;
const #49 = NameAndType #66:#67;// toString:()Ljava/lang/String;
const #50 = class #68; // java/io/PrintStream
const #51 = NameAndType #69:#70;// println:(Ljava/lang/String;)V
const #52 = class #71; // java/lang/Thread
const #53 = NameAndType #72:#73;// sleep:(J)V
const #54 = Asciz java/lang/Object;
const #55 = Asciz java/lang/String;
const #56 = Asciz java/util/List;
const #57 = Asciz java/lang/InterruptedException;
const #58 = Asciz add;
const #59 = Asciz (Ljava/lang/Object;)Z;
const #60 = Asciz java/lang/System;
const #61 = Asciz out;
const #62 = Asciz Ljava/io/PrintStream;;
const #63 = Asciz append;
const #64 = Asciz (Ljava/lang/String;)Ljava/lang/StringBuilder;;
const #65 = Asciz (I)Ljava/lang/StringBuilder;;
const #66 = Asciz toString;
const #67 = Asciz ()Ljava/lang/String;;
const #68 = Asciz java/io/PrintStream;
const #69 = Asciz println;
const #70 = Asciz (Ljava/lang/String;)V;
const #71 = Asciz java/lang/Thread;
const #72 = Asciz sleep;
const #73 = Asciz (J)V;
{ //方法区
public double[] spaceStone; 5、字段信息;
public com.myjava.test.Test(); 6、方法信息;
Code:
Stack=2, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: sipush 10000
8: newarray double
10: putfield #2; //Field spaceStone:[D
13: return
LineNumberTable:
line 18: 0
line 20: 4
public static void main(java.lang.String[]) throws java.lang.InterruptedException; 6、方法信息;
Code:
Stack=3, Locals=5, Args_size=1
0: ldc #3; //String 1
2: astore_1
3: new #4; //class java/util/ArrayList
6: dup
7: invokespecial #5; //Method java/util/ArrayList."<init>":()V
10: astore_2
11: iconst_0
12: istore_3
13: new #6; //class com/myjava/test/Test
16: dup
17: invokespecial #7; //Method "<init>":()V
20: astore 4
22: aload_2
23: aload 4
25: invokeinterface #8, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
30: pop
31: getstatic #9; //Field java/lang/System.out:Ljava/io/PrintStream;
34: new #10; //class java/lang/StringBuilder
37: dup
38: invokespecial #11; //Method java/lang/StringBuilder."<init>":()V
41: ldc #12; //String
43: invokevirtual #13; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
46: iload_3
47: iinc 3, 1
50: invokevirtual #14; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
53: invokevirtual #15; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
56: invokevirtual #16; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
59: ldc2_w #17; //long 100l
62: invokestatic #19; //Method java/lang/Thread.sleep:(J)V
65: goto 13
LineNumberTable:
line 23: 0
line 24: 3
line 25: 11
line 27: 13
line 28: 22
line 29: 31
line 30: 59
line 31: 65
StackMapTable: number_of_entries = 1
frame_type = 254 /* append */
offset_delta = 13
locals = [ class java/lang/String, class java/util/List, int ]
Exceptions: 7、 异常表
throws java.lang.InterruptedException
}
其余还可能会有:
●任何直接超接口的全限定名的有序列表。
●类静态变量。
●指向ClassLoader类的引用。任何类都需要被类装载器装入内存。如果是被用户自定义类装载器装载的,那么JVM必须在类型信息中存储对该装载器对象的引用。
●指向Class类的 引用。对于每一个被装载的类型,虚拟机都会相应的为它创建一个java.lang.Class类的实例,而且虚拟机还必须以某种方式把这个实例和存储在方 法区中的类型信息关联起来。
●方法表。 为了能快速定位到类型中的某个方法。JVM对每个装载的类型都会建立一个方法表,用于存储该类型对象可以调用的方法的直接引用,这些方法就包括从超类中继 承来的。
好了,终于把所有class二进制文件都读进来了, 下一步执行。
从哪开始呢?
main? static块?
当然,执行是从main方法开始的,但是加载的时候static块就完事了。
相关文章
- 暂无相关文章
用户点评