------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
首先要了解Java的内存结构,我们首先来分析一下一个Java程序的执行过程。
请看下面的图,我会来详细解释。
1.当创建一个例如Hello.java的文件后,我们要对其进行编译,命令 : javac Hello.java 将其编译成一个class文件,该文件成为字节码文件。
因为java应用程序必须通过java虚拟机中的java解释器(java.exe)来解释执行其字节码文件。
2.一旦运行编译后的字节码文件,程序就将自己从硬盘中Load到内存区,操作系统有一些代码也是存在内存中的,操作系统会找到被Load到内存中的代码,
然后从代码的main方法开始执行。
3.下来就到了程序在执行过程中,内存的管理。内存分为4块区域。
(1) stack(栈):存放局部变量和对象的引用,即存放变量,并且是非静态变量。
(2) heap(堆):存放new产生的数据.
(3) data segment(数据域):分为静态域和常量域。
静态域:存放在对象中用static定义的静态成员(即静态变量,同理,如果该静态变量是基本类型则将变量名和值存入静态域,如果是引用类型则指向new出的对象)。
常量池:常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如:类和接口的全限定名;字段的名称和描述符;方法和名称和描述符。
(4) code segment(代码区):存放代码。
4.下面我来举几个例子,帮助大家理解。
String s1="i love you,黑马";
解析:这里的sl是非静态变量应该存放在栈中,字符串"i love you,黑马"是常量,所以应该存放在常量池中。
String s2=new String("黑马,我来了");
解析:s2是非静态变量,所以存放在栈中,new出来的对象存放在堆内存中,对于常量值"黑马,我来了"应该存放在常量池中。
static int a=10;
解析:静态变量a需要放入静态域中,对于变量值10则应该放入到常量池当中。