JVM组成结构

 

 

1.程序计数器(Program Counter Register)

作用:记住下一条jvm指令的执行地址

特点:1.线程私有:每个线程有一个独立的程序计数器,随线程创建而创建,随线程结束而死亡。

   2.无内存溢出(OutOfMemoryError):在编译时已经确定该线程代码的偏移量最大值,不会出现内存溢出

   3.①执行java方法,计数器记录虚拟机字节码指令的地址;②执行native方法,计数器为空

 

2.虚拟机栈(Java Virtual Machine Stacks)

2.1定义

每个线程运行时所需要的总内存,被称为虚拟机栈。

每个栈有多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存。

每个线程只有一个活动栈帧,对应着当前正在执行的那个方法。

 

 回答:
1.不涉及,GC主要针对的是堆空间的内容。

2.栈内存越大,总内存不变的情况下,栈(线程)总数目越少。

3.(1)如果局部变量没有逃离方法的作用范围,则是线程安全的。

 (2)如果局部变量引用了对象,并逃离方法的作用范围,则需要考虑线程安全。(逃逸行为)

2.2栈内存溢出

1.**栈帧过多**导致栈内存溢出
2.**栈帧过大**导致栈内存溢出

2.3线程运行诊断

案例1:cpu占用过多
定位:
- 用top定位哪个进程对cpu的占用过高
- ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)
- jstack 进程id(可以根据线程id找到有问题的线程,进一步定位到问题代码的行处)

Tips:pid、tid分别为process id和thread id,nid为 Native Thread id(系统线程)

案例2:程序运行很长时间没有结果

 

3.本地方法栈(Native Method Stack)

为了与操作系统底层进行交互,引入了一些用c/c++编写的方法——用关键字 native 修饰

本地方法栈:为本地方法的运行提供内存空间

 

4.堆(Heap)

4.1定义

通过new关键字,创建对象都会使用堆内存。

特点:

它是线程共享的,堆中对象都需要考虑线程安全的问题。

有垃圾回收机制(GC)。

4.2堆内存溢出

4.3堆内存诊断

1.jps工具:查看当前系统中有哪些java进程

2.jmap工具:查看堆内存占用情况(某时刻)jmap -heap 进程id

3.jconsole工具:图像界面的,多功能的监测工具,可以连续监测

4.jvisualVM工具:jconsole增强版

案例:

垃圾回收后,内存占用仍然很高

 

5.方法区(Method Area)

5.1定义

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域。

它存储已被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。

5.2特点

1.方法区是线程共享的,多个线程都用到一个类的时候,若这个类还未被加载,应该只有一个线程去加载类,其他线程等待;

2.方法区的大小可以是非固定的,jvm可以根据应用需要动态调整,jvm也支持用户和程序指定方法区的初始大小;

3.方法区有垃圾回收机制,一些类不再被使用则变为垃圾,需要进行垃圾清理。

5.3方法区内存溢出

1.6以前会导致永久代内存溢出

1.8以后会导致元空间内存溢出

5.4运行时常量池

1.8以前方法区包含StringTable,1.8以后将运行时常量池划给了堆

常量池,就是一张表,虚拟机指令根据这张常量池表找到要执行的类名、方法名、参数类型、字面量等信息

运行时常量池,常量池是*.class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

posted on 2022-11-22 15:21  HHHuskie  阅读(19)  评论(0编辑  收藏  举报

导航