java 内存模型简单理解

java的运行时内存主要包含以下几个区域:

1、程序计数器:线程独有,是最少的内存区域,没有规定任何的异常抛出。

2、java 栈 :线程独有,分别有java虚拟机栈和本地方法栈(执行native方法) hotspot已经合并这两个区域。这个区域可以抛两中异常outofmemoryerror(动态扩展内存,但也申请不到内存,例如无线创建线程) 和stackoverflowerror(超出规定的栈大小),栈在执行方法时会创建一个栈帧,一个方法对应一个栈帧,栈帧包含操作数栈(用户存储计算参数和计算结果,在方法调用时,也用来准备调用方法的的参数以及接收方法的返回结果)、局部变量表,表的大小在编译期间已经确定大小,局部变量表的最少单位为slot(根据不同机器规定的大小不一样)。

3、java堆 全局共享,要实现自动内存管理 会出现outofmemoryerror异常

4、方法区和常量池,方法区存放常量、静态变量、方法信息、编译器产生的代码信息(这个区域不要实现自动内存管理),可能出现outofmemoryerror

   常量池是方法区的一个部分。作用是存储java类文件常量池中的符号信息

5、永久代:

在JDK1.2到JDK1.6 hotSpot使用永久代实现方法区 ,java7之后就没有永久代的概念,改用java heap来实现。

6、intern 方法的意思是从字符串常量池拿区字符串地址,比如:String a = new String(“123”).intern()  a == “123” 是返回true的,如果字符串池没有,就把当前的字符串地址放进字符串池当中。eg:String a = “123”; 其实是创建了一个123的字符串对象,并且发这个对象放到字符串池中,如果再有String b = “123”;这个时候使用的其实是字符串池中的对象,所以 a == b 必然是ture。 另外一下代码,在java6 和java 7是有区别的

public class Test {
    public static void main(String[] args) {
       // String a = "123";
        String b = new String("123");
        String c = new StringBuilder("abc").append("def").toString();
        System.out.println(b.intern() == b);
        System.out.println(c.intern() == c);//1.7返回ture,1.6返回false

 因为java7和java6的常量池的实现区域不一样了,java6是在永久代,而java7已经在java heap中实现,上面的例子,abcdef这个字符串是在常量池中没有,所以就把c对象的地址放到常量池中,而1.7的话就是直接把堆中地址返回就行,所以返回true,而java6 其实是要在永久代这块区域重新建一个对象,返回一个地址,所以必然和c对象的地址不一样。

    原文作者:java内存模型
    原文地址: https://blog.csdn.net/sonycong/article/details/61414702
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞