深入理解Java虚拟机(一)内存区域划分

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kukubao207/article/details/88989970

Java虚拟机管理的内存包括以下几个运行时数据区

一、程序计数器

  • 线程私有
  • 指示当前线程所执行到的字节码的行号。
    因为Java会有多线程切换,从老线程切换到某个新线程时,需要知道新线程当前已经执行到哪里了,也需要保存老线程已经执行到哪了,方便以后切回去的时候继续往下执行。

二、虚拟机栈

  • 线程私有
  • 每一个方法的执行到完成对应一个帧栈在虚拟机栈中的入栈到出栈的过程。
  • 帧栈中保存方法的局部变量表、动态链接、操作数栈、方法出入口等内容
  • 局部变量表存放基本数据类型、对象引用和returnAddress(下一条字节码指令地址)。
  • 通过-Xss调整栈的大小
  • StackOverFlowError和OOM Error

三、Native方法栈

  • 他和虚拟机栈是类似的,只不过他是为Native方法服务的。
  • StackOverFlowError和OOM Error

四、Java堆

  • 线程共享
  • 对象分配的主要区域
  • 垃圾回收的主要区域(新生代、老年代)
  • 可以通过-Xmx -Xms来指定大小
  • OOM Error

五、方法区

  • 存放类加载后的类信息、代码、常量、静态变量
  • 有一个常量池,常量池中存放字面量和符号引用,翻译后的直接引用。
  • 很少需要垃圾回收,因此有人把这个区域叫做永久代。
  • OOM Error
    字面量就是比如说int a = 1; 这个1就是字面量。又比如String a = “abc”,这个abc就是字面量。

字面量:
就是比如说int a = 1; 这个1就是字面量。又比如String a = “abc”,这个abc就是字面量。
符号引用和直接引用:
在java中,一个java类将会编译成一个class文件。在编译时,java类并不知道引用类的实际内存地址,因此只能使用符号引用来代替。比如org.simple.People类要引用org.simple.Tool类,在编译时People类并不知道Tool类的实际内存地址,因此只能使用符号org.simple.Tool(假设)来表示Tool类的地址。而在类装载器装载People类时,此时可以通过虚拟机获取Tool类 的实际内存地址,因此便可以既将符号org.simple.Tool替换为Tool类的实际内存地址,及直接引用地址。

六、直接内存

  • 他的大小和堆大小相加最多不超过操作系统内存上限。
  • 可以通过 -XX:MaxDirectMemorySize调整大小

猜你喜欢

转载自blog.csdn.net/kukubao207/article/details/88989970