JVM学习(1)-JVM运行时数据区
JVM学习(1)-JVM运行时数据区
haoran_10 发表于1年前
JVM学习(1)-JVM运行时数据区
  • 发表于 1年前
  • 阅读 9
  • 收藏 0
  • 点赞 0
  • 评论 0

导言:java是基于一门虚拟机的语言,所以了解并且熟知虚拟机运行原理非常重要。

 

先整体看一张java虚拟机技术图:



 

一、堆

1、方法区,Method Area,主要存放已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。

又称为永久代。

 

比如spring 使用IOC或者AOP创建bean时,或者使用cglib,反射的形式动态生成class信息,

如果生成大量的动态类,造成堆内存不足,则会抛出OutOfMemoryError异常。

又比如tomcat把jsp编译成servlet类的时候,也会造成这种情况。

 

2、运行时的常量池:是方法区的一部分。用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。常量池有动态性,可以添加数据。比如string常量池,imtern()。其实就是享元模式的一种实现。

 

运行时常量池溢出:比如一直往常量池加入数据,就会引起OutOfMemoryError异常

 

3、java堆,java heap。是java虚拟机所管理的内存中最大的一块。是所有线程共享的一块内存区域,在虚拟机启动时创建。存放对象实例,数组。而垃圾收集器管理的主要区域也是这个区域,也被称为GC堆。

分为新生代和老年代。

当对象大量生成造成内存不足时,也会抛出异常。

 

二、栈

1、虚拟机栈,是线程私有的,与线程的生命周期相同。描述的是java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,用于存放局部变量表(基本类型、对象引用)、操作数栈动态链表、方法出口等信息。

如果一个线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常, 比如递归调用。

如果线程生成数量过多,无法申请足够多的内存时,则会抛出OutOfMemoryError异常。比如tomcat请求数量非常多时,设置最大请求数。

 

2、本地方法栈,Native Method Stack。也就是调用虚拟机使用到的Native方法服务。也会抛出以上两种异常。

 

3、程序计算器。当前线程所执行的字节码的行号指示器。

 

三、直接内存

并不是虚拟机运行时数据区的一部分。JDK1.4引入的nio,可以使用Native函数库直接分配堆外内存,然后通过一个存储在java堆里面的DiectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中提高性能,因为避免了java堆和Native堆中来复制数据。

 

 

四、小结

虚拟机内运行时数据区整体就是上面所述,所有java对象分配回收等一系列的操作都在上述数据区,我们自己也根据虚拟机规范写一个java虚拟机,也要遵循以上原则。

 

标签: java虚拟机 java jvm
共有 人打赏支持
粉丝 27
博文 88
码字总数 80846
×
haoran_10
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: