JVM之Java内存结构
Posted 浅谈Java基础
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM之Java内存结构相关的知识,希望对你有一定的参考价值。
Java内存结构的几大部分如下图:
接下来,会对上面每部分区域的功能一一解释。
2、虚拟机栈:是线程私有的,该区域所描述的是Java方法执行的动态内存模型,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息,局部变量表存放的是编译期可知的基本数据类型,引用类型,returnAddress等,局部变量表的内存在编译期完成分配,进入方法后,这个方法需在帧中分配多少内存是固定的,在方法运行期间不会改变局部变量表的大小。如果说栈帧堆满了整个栈,会出现StackOverflowError(栈溢出)异常,栈也可以申请更大的内存,如果申请不到,会抛出OutOfMemoryError异常。
3、本地方法栈:是为本地的native方法服务的,其他的都和虚拟机栈一样。
4、堆:线程共享的一块区域,用来存放对象实例的(由于现在有了逃逸分析技术,也可以将对象分配在栈上),该区域是垃圾回收的主要区域,垃圾回收主要是分代回收,有年轻代和老年代,堆可以是物理上不连续的区域,只要逻辑上连续即可。在堆中分配内存的方法有碰撞指针(前提是区域绝对规整,注意多线程同步问题,可以采用CAS原理加失败重试实现或者本地线程分配缓冲)和空闲列表(不是规整的内存,就是有一个表记录空闲的内存,然后分配后,从该表中去除),堆空间不足时会出现OutOfMemoryError异常。
5、方法区:线程共享的区域,存储JVM加载的类信息(类的版本,字段,方法,接口),常量,静态变量以及即时编译后的代码等数据。方法区还有一块运行时常量池,class文件中的常量池在类加载后就被放入运行时常量池,运行时常量池相对于class文件的常量池具有动态性,可以在运行期间通过intern将常量放入运行时常量池中,方法区空间不足时会抛出OutOfMemoryError异常。
除了Java虚拟机规定的这几块区域以外呢,还存在一个堆外内存,即直接内存,直接内存能减少IO时的内存复制了,实现零拷贝,而且没有GC,减少了垃圾回收的工作,加快了复制的速度,该区域也难以控制,如果内存泄漏很难排查。
以上是关于JVM之Java内存结构的主要内容,如果未能解决你的问题,请参考以下文章