详解Jvm内存结构

Posted hymKing

tags:

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

近期在学习研究内存,那么Jvm内存结构和Jvm的内存模型即JMM(Java momery model)这两项内容都是学习java虚拟机、java内存知识的基础。为了让自己加深理解,有不至于嵌入到底层细节太深,会通过一段代码片段类比到内存结构图中的真实呈现。

一、Jvm体系的内存结构图

JVM运行数据区,也就是我们所说的内存结构主要分为两个大区:

1、线程共享区

**方法区(Method Area)😗*存储运行时的常量池、被虚拟机加载过的类信息、常量、静态变量、即时编译器编译后的代码数据。

**堆区(Heap Area)😗*所有的对象实例以及数组都要在堆上分配,也是垃圾回收器主要管理的对象。

2、线程独占区

**虚拟机栈:**又称Java栈,存储局部变量表、操作栈、动态链接、方法出口,对象指针。

**本地方法栈:**为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行,android中的Jni本地方法调用亦该如此。

**程序计数器:**当前线程执行的字节码的行号指示器。

接下来我们通过一段简单的代码来看实际内存结构图

二、内存结构图实例分析

先看实例代码:

public class MemoryStructure 
    static  int sSize =10;//静态变量 方法区
    static MemoryObj memoryObj=new MemoryObj(sSize);//声明部分(静态类变量)放在方法区,对象实例在堆中
    int initSize=20;//类的成员变量 堆区
    MemoryObj memoryObj2=new MemoryObj(initSize);//声明部分(引用类型成员变量),实例都在 堆中
    public static void main(String[] args) 
        //MemoryStructure memoryStructure 声明部分(引用类型) 放在虚拟栈
        MemoryStructure memoryStructure = new MemoryStructure();
        int size3=30;//栈区
        //MemoryObj memoryObj3声明部分(引用类型) 放在虚拟栈
        MemoryObj memoryObj3= new MemoryObj(size3);

        //新开线程 :新的独享虚拟栈
        new Thread()
            @Override
            public void run() 
                int k=40;//栈区
                setSize(40);
            

            void setSize(int size)
                memoryStructure.memoryObj2.size=size;
                //说明:
                //新线程访问主线程的局部变量是无法访问的,当前编译器没有报错,是因为idea工具编译做了处理
                //查看一下编译后的字节码:  final MemoryObj memoryObj3 = new MemoryObj(size3);        
                MemoryObj temp=memoryObj3;
            
        .start();
    


class MemoryObj
    int size;
    public MemoryObj(int size) 
        this.size = size;
    

上述代码,对照内存结构图的分布位置如下:

正如代码中的注释和上述代码片段在各区中的分布图,能很清晰的知晓Jvm的内存结构。

补充一些堆和方法区的理解,虽然Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java 堆区分开来。

方法区是为类信息服务的,存储类信息、常量、静态变量。成员变量直接存在在堆中。

虚拟栈区可以理解成为程序的执行服务的,方法中定义的局部变量,被保存在这个位置,最终方法的执行是通过出栈压栈的方式执行。

方法区、堆区是共享区域;虚拟栈区是独享区域

每一个线程都会对应一个虚拟栈(又称java栈),上述newThread中的MemoryObj temp=memoryObj3;,若memoryObj3是无final修饰,是无法直接访问的,栈内数据是独享的。

这篇是通过一个实例分析的方式,对jvm的内存结构有了更清晰的认识。如若想做更深度的了解,推荐《深入理解 Java 虚拟机》这本书籍。
获得更多更新,关注gongzhonghao:Hym4Android

以上是关于详解Jvm内存结构的主要内容,如果未能解决你的问题,请参考以下文章

详解Jvm内存结构

jvm内存

Jvm(30),理解升级----Java中堆内存和栈内存详解

Java虚拟机详解02----JVM内存结构

(超详解)JVM-内存结构

Java GC的工作原理详解