1 JVM把管理的内存划分不同区域,一些区域随JVM启动而存在,一些区域依赖于用户线程的生命周期。
2 JVM管理的内存包括这几个区域:
程序计数器,Java虚拟机栈,本地方法栈。(线程单独使用)
Java堆,方法区,常量池,直接内存。(线程共享)
程序计数器 Program counter register |
- 告诉JVM(?)当前线程下一条指令的地址
- 如果执行Native方法,则为空
- 此区域没有OutOfMemoryError,其他都有
|
虚拟机栈(JVM Stack) |
- 为JVM使用的java 字节码服务
- 方法在执行的时候创建一个stack frame 入栈,执行完后出。
- stack frame存储了局部变量表,操作栈,动态链接,方法出口等。
- 局部变量表的内存空间在编译时完成,运行时不会变化。
- 如果请求的栈大于允许的,stackoverflowerror.
- 如果JVM Stack动态扩展时,申请不到了,outofmemoryerror
|
本地方法栈(Native Method Stack) |
- 为JVM使用的native method服务
- 也会抛出outofmemoryerror和stackoverflowerror
|
java heap堆 |
- 所有线程共享,jvm启动时创建
- 存放对象实例
- GC管理的主要区域
- -Xms -Xmx调节大小
- 会抛出outofmemoryerror
|
java method area 方法区 |
- 存放被jvm加载的类 常量 静态变量 即时编译的代码
- 可以叫永久代
- 内存回收的对象是常量池的回收和类型的卸载。
- 方法区无法满足内存分配需求时,outofmemoryerror
- 包括运行时的常量池,存储符号引用和直接引用(一部分常量在编译时产生,如final String "abc",但是也可以动态产生,如intern()方法)
|
直接内存 |
- 不会受到java heap限制,但是受到物理内存和寻址空间的限制
- 如果sum(各个区域内存)>物理内存,outofmemoryerror
- 可以提高性能,避免java heap 和 native heap中来回复制数据(NIO 类的使用)
|
参考:
https://my.oschina.net/OutOfMemory/blog/299525
http://www.tuicool.com/articles/6vQ3am
http://chenzhou123520.iteye.com/blog/1585224