java虚拟机内存区域理解

Posted dream_sky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java虚拟机内存区域理解相关的知识,希望对你有一定的参考价值。

java虚拟机有的区域随着虚拟机进程的启动而存在,
有的区域依赖用户线程的启动和结束而建立和销毁。
  • 程序计数器:为了线程切换后能恢复到正确的执行位置,每个线程都有一个独立的程序计数器。(针对java方法,即栈)
  • 虚拟机栈:为了虚拟机执行java方法,线程创建时就会创建一个栈帧,存储局部变量表、操作数栈、动态链接等。
       StackOverFlowError:线程请求的栈深度大于虚拟机所允许的深度;
       OutOfMemoryError:动态扩展是无法申请到足够的内存。
  • 本地方法栈:为了虚拟机使用到Native法服务。
  • 堆:存放对象实例和数组,为对象实例分配内存。可分为新生代和老年代。可以处于物理上不连续的内存空间中,只要逻辑上连续即可。
            -Xmx和-Xms控制大小。
  • 方法区:存储类信息、常量、静态变量、编译后的代码等数据。也叫“永久代”,可以像Java堆一样管理这部分内存。
                    1.6以后将字符串常量池放入了堆空间。
  • 运行时常量池:存放编译期生成的各种字面量和符号引用。
                intern()方法设计的初衷,就是重用String对象.如下测试验证。
<wiz_code_mirror>
 
 
 
 
 
        String a1 = new String("dog") + new String("Pig");//不会在常量池创建对象。
//        String a1 = new String ("dogPig");//在常量池和堆空间创建对象
        System.out.println(a1 == a1.intern());//在常量池查找不存在,1.6直接生成。1.7直接生成后,指向堆空间的引用。
        System.out.println(a1 == "dogPig");//true
        String str2 = "dogPig";//新加的一行代码,其余不变
        System.out.println(a1 == str2);//true
 
 

内存分配: 

桟:存储对象的引用,局部变量的基本数据类型,速度快,自动销毁;
堆:存储new出来的对象,数组,成员变量的基本数据类型;
常量池:属于方法区,存储final的变量和方法;
静态域:属于方法区,存储static的变量和方法;
方法区:存储二进制class字节码。

 

Demo demo=new Demo();  

 这一条语句,其实包括了四个动作:

     1)右边的“new Demo”,是以Demo类为模板,在堆空间里创建一个Demo对象。
     2)末尾的()意味着,在对象创建后,立即调用Demo类的构造函数,对刚生成的对象进行初始化。 
     3)左边的“Demo demo”创建了一个Demo类引用变量,它存放在栈空间中。也就是用来指向Demo对象的对象引用。 
     4)“=”操作符使对象引用指向刚创建的那个Demo对象。

 

 

以上是关于java虚拟机内存区域理解的主要内容,如果未能解决你的问题,请参考以下文章

《深入理解Java虚拟机》笔记02:Java内存区域与内存溢出异常

《深入理解JAVA虚拟机》——学习笔记

java虚拟机内存区域理解

深入理解Java虚拟机——java内存区域与内存溢出异常

深入理解JAVA虚拟机读书笔记——Java内存区域与内存溢出异常

回顾《深入理解 Java 虚拟机》之 Java 内存区域