JAVA基础-----------JVM内存分析之HelloWorld.java

来源:互联网 发布:淘宝图片上传尺寸 编辑:程序博客网 时间:2024/06/07 17:47

JVM内存分析之HelloWorld.java


HelloWorld.java源码如下:


publicclass HelloWorld {

    publicstatic void main(String[]args) {

       String s ;

       s ="HelloHorld!";

       System.out.println("s = " +s);

    }

 

}

 


画图分析:

 



JVM执行分析:

首先自然是将源码进行编译啦!生成HelloWorld.class的字节码文件。

输入java  HelloWorld的命令运行java程序时,系统收到指令,就会创建java虚拟机线程,这个进程开始从classpath中找到HelloWorld.class文件,读取这个文件中的二进制数据,然后把HelloWorld类的类信息存放到方法区的类代码区中。这一过程称为类的加载过程

之后JVM主线程会去找main()这个主方法,开始执行方法里面的指令。main()方法中形参args是字符串数组类型的,因为String[]也是一个对象,所以在堆中开辟属于它的内存空间。可以通过键盘输入参数传递给args这个形参,保存在String[]的内存空间中。

第一条指令String  s;由于这个变量是在main()方法里面,它是一个局部变量,所以jvm就为它栈中开辟了一块空间。

s = ”HelloWorld”中, ”HelloWorld”是常对象,在方法区的数据区的常量数据区开辟内存空间,开辟好空间后将这块空间的地址付给了变量s,所以变量s存放的是地址,而不是”HelloWorld”这个字符串。

       System.out.println(“s= ” + s)中,因为System是java标准类库中的类,位于java,lang下,这个包是在java程序启动时候,JVM的classLoder就会直接将它加载进来的,所以不需要人工手动导入就可以直接使用,这个System类在堆中开辟了三块地址空间,分别属于System.in,System.out,System.error。System.out.println()复写了objecttoString()方法,得到返回来的s所指向地址的值,然后向控制台输出,最后换行。

输出结果:s = Hello Horld!

 


附加1:类装载器装载字节码的具体过程

     一个类装载器本身也是一个java类,所以,类装载器自身也需要被另外一个类装载器装载,这就出现了类似先有蛋,还是先有鸡的问题。但JAVA中的类装载器的这个问题却很容易解决。JAVA的虚拟机(JVM)中内嵌了一个称为Bootstrap类装载器,它是用特定于操作系统的本地代码实现的,属于JAVA虚拟机的内核,Bootstrap类不用专门的类装载器去进行装载。Bootstrap类负责加载JAVA核心包中的类(即rt.jar文件中的类),这些类的Class.getClassLoader()方法返回值为null,即表示是Bootstrap类装载器。JAVA核心包中有另外两个类装载器:ExtClassLoader和AppClassLoader,它们都是用JAVA语言编写的JAVA类,其中ExtClassLoader类装载负责加载存放在<JAVA_HOME>/jre/lib/ext目录下的jar包中的类,AppClassLoader负责加载应用程序的启动执行类,即当使用java命令去启动执行一个类时,JAVA虚拟机使用AppClassLoader加载这个类。在编译和运行JAVA程序时,都会通过ExtClassLoader类装载器去<JAVA_HOME>/jre/lib/ext目录下的JAR包中搜索要加载的类,所以,如果将包含例如Servlet API的jar包或者是javamail.jar包复制到该目录下,在编译Servlet或JavaMail程序时,就不必在CLASSPATH环境变量中增加包含ServletAPI的jar包或者是javamail.jar包文件。

 

附加2:关于为什么main()方法为什么要用publicstatic void修饰?

       JVM在执行java程序调用main()方法时候,不会创建这个类的实例,而是通过类名加方法名直接调用,因此需要修饰为 public static 。另外在java中对于main()方法的使用,JVM有限制,不能有返回值(因为这个类都没有进行实例化,没有能够接受返回值的载体),因此用void修饰。

 

附加3  HelloWorld.java的另一个版本

public class HelloWorld2 {

    static {

         String s;

         s = “Hello World2!”;

         System.out.println("s = " + s);

    }

    public static void main(Stringargs[]){

        System.exit(0);

    }

}

这个版本中的main()方法执行的指令只有"System.exit(0);",目的是让程序正常结束。那“HelloWorld!”是从哪里打印的?其实就是在static{…….}打印的,因为static代码块的内容会在main调用前调用。

个人学习心得,欢迎批评指正                                                         ------   isunnyvinson                             

                                                                                                                                                                                                            


1 0
原创粉丝点击