一、Java内存模型   

 先来看个图

JavaMelody内存图 java内存模型图_java

这个图把Hotspot的实现放到里边,技术不精,如果有问题,大家看到了请指正。

Java内存模型中规定:所有变量都存储在主内存区域,不能直接操作变量,每个线程需要将变量从主内存load到自己的工作内存中进行计算,然后save到主内存中,这个图大概就是这个意思。

Java内存模型(Java Memory Model)是一个逻辑上的概念,上面这个图中和多核CPU的操作系统一样,我们可以看出,多线程对一个共享变量的操作就会涉及到数据一致性问题。

所以在编程的时候,需要考虑线程安全问题。

二、JVM内存结构(运行时数据区)

JavaMelody内存图 java内存模型图_jvm_02

1、程序计数器

       每个线程都有自己的pc(程序计数器)寄存器;

       在任何时候,每个线程都在执行一个方法的代码,即该线程的当前方法;

       由于在同一时间CPU上只有一个指令执行,所以我们的程序需要记录执行到哪一步,以便下一次轮到CPU时间的时候正确的执行。可以简单的认为程序计数器就是用来保留现场。

2、JVM栈

    每个线程有一个自己的栈,每个方法对应一个栈帧。在一个线程中可能会有多个方法调用执行,每个方法会以栈帧的形式放入栈中,通过入栈出栈完成调用。

JavaMelody内存图 java内存模型图_jvm_03

假设每个线程占用1M内存的话,我们可以看出栈的深度是有限制的(比如递归调用层次深度),否则就会溢出。

栈帧的结构我们也可以简单的用jclasslib来看。

3、本地方法栈

     native方法运行使用。

4、堆

     堆是线程共享的区域,用来存储Java对象实例,可以说几乎所有对象都被创建分配到堆内存中。垃圾回收就是在做这一块内存的清理。整个堆被分为年轻代、老年代。年轻代又分为Eden区和两个大小相同的s0、s1区。 不同的代又适用于不同的垃圾回收算法(GC)。内存调优主要就是针对堆来做优化。

5、方法区

    方法区是一个逻辑概念,在jdk1.8中实现为元空间,直接占用系统内存,默认无限制,大小为系统物理可用内存。(参数为:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N

关于运行时常量池和直接内存先不写了。