接(一)http://blog.csdn.net/molu_chase/article/details/52352223
1.1.java内存介绍,堆栈的区别,堆栈介绍,堆中常量池和新建的对象保存的地方
先讲一下缓存,从内存的角度讲,由于计算机存储设备的读写和其处理器的运算的时间差距很大,所以需要在其中加一层读写速度尽可能接近处理器运算速度的高速缓存。
借用一张图来说明多处理器,多缓存,内存之间的关系【1】
下面再来讲Java内存机制
Java把内存一般分为两块,堆和栈
简单来说,堆就是存放动态数据,如new出的对象和数组,当然常量池也在堆中。而栈中则是存放一般的数据类型,这里包括对象的引用,其指向对象的地址。
更近一步,堆中的数据是归Java虚拟机管的,而虚拟机并不一定会在对象无引用的时候销毁对象(只有当内存不够的时候),这样就造成了Java比较占内存。而栈中则是没有使用便销毁,比如对于一个for语句定义的变量,在跳出for循环后,就会得到销毁。【2】【3】
接下来讲一下常量池
常量池分为静态常量池和运行时常量池,静态常量池是.class文件中的常量池。运行时常量池是jvm将.class中的加载进方法后的,也叫方法区的运行时常量池。
关于其中的关系,有这么一句话:运行时常量池相对于CLass文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法。【4】
有一篇文章讲的很不错,只有当是字符串的赋值,该变量才指向的是常量池,但凡是变量的赋值,都不会指向常量池
例如String s1="ss";String s2="df";String s3="ss"+"df";String s4=s1+s2;
其中s3是常量,但是s4就不是,因此s3==s4为false【5】
还有代码区和数据区
代码区是用来存放从硬盘上读取的源程序代码
数据区是用来存放static定义的静态成员
关于new的对象不得不让我们想起了其他的其中生成对象的方法
讲讲通过类加载机制来生成的对象,即通过Class.forName()调用启动类的加载器,获取类类型,然后通过类类型的newInstance()方法获取对象,不过在newInstance()中仍然new的对象再返回,因此其仍然是存在堆中。【6】
参考
1.http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html
2.http://www.cnblogs.com/xwdreamer/archive/2012/04/01/2428857.html
3.http://blog.csdn.net/shimiso/article/details/8595564
4.http://www.jianshu.com/p/c7f47de2ee80
5.http://www.cnblogs.com/iyangyuan/p/4631696.html
6.http://www.jb51.net/article/42648.htm