java中内存分为:Heap,Stack。
(深刻理解String s=new String("xoxo")和String s=" xxoo"的区别)
Heap(堆):这里存放类的实例对象和已分配内存的数组,其中细分为Constant Pool(常量池),方法代码,以及static成原变量和方法。
运行时常量池(runtime constant pool),它包括了关于类,方法,接口等中的常量,也包括字符串常量 。
方法代码(method code),即线程要执行的方法代码
静态变量和方法(static variables and method),我们定义的static类型的变量和方法都存放在这里
Stack(栈):
.每个线程都有自己独占的stack,里面存放的是当前线程执行的method及其局部变量,我们对对象的引用也放在这里。
当我们创建一个对象通常分两种情况:对象类型--new Object() 和基本类型(primitive type,8种。注:String 不是的)。
对象 类型:T t=new T()和 T Class类反射方式。这种情况,比如说,String s=new String("xoxo")要运行,堆中先要在常量池中找是否有“xoxo”,如有:则常量池不变;如果没有:就要在常量池中新建一个“xoxo”(生成一个对象)。然后由于newString("xoxo"),在堆中会新建一个String对象(又生成一个对象)并用常量池中的“xoxo”作为参数。在stack中放入一个 String s的引用( 引用(reference/stack pointer)占内存,但不是对象,存入了new String(....)对象的地址 )。 对于String s="xxoo";JVM会先去heap里的constant pool看一看有没有字符串''xxoo"",如果没有:那么在这个pool中创建一个“xxoo”(一个对象生成),并且将地址放入(reference/stack pointer String s中。
8种基本类型:例如int i=1; boolean a=true.....对于这些并不是引用(reference/stack pointer)!而且他们均存储在栈stack中。(《thinking in java 》 That is, instead of creating the variable by using new, an “automatic” variable is
created that isnot a reference. The variable holds the value directly, and it’s placed on the
stack, so it’s much more efficient.)
堆heap,栈stack中所占内存占用和释放的比较:
栈stack在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。
堆heap:程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。