JVM本地方法栈、堆和方法区

734 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

3.本地方法栈

image-20220331134651233

一些带有native关键字的方法就是需要JAVA去调用本地的C或者C++方法,因为JAVA有时候没法直接和操作 系统底层交互,所以需要用到本地方法

4.堆

image-20220331134733782

(1)定义

  • 通过new关键字创建的对象都会被放在堆内存

(2)特点

  • 所有线程共享,堆内存中的对象都需要考虑线程安全问题
  • 有垃圾回收机制

(3)堆内存溢出

  • java.lang.OutofMemoryError :java heap space. 堆内存溢出

(4)堆内存诊断

  • jps :查看当前系统中有哪些 java 进程
  • jmap :查看堆内存占用情况 jmap - heap 进程id
  • jconsole :图形界面的,多功能的监测工具,可以连续监测
  • jvirsalvm

5.方法区

image-20220331135147613

(1)定义

  • 方法区与java堆一样,是各个线程共享的内存区域
  • 方法区在jvm启动的时候被创建,并且它的实际物理内存空间和java堆区一样都是可以不连续的
  • 方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展
  • 方法区的大小,决定了系统可以保留多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机也会抛出内存溢出错误
  • 关闭jvm就会释放这个区域的内存

(2)组成

image-20220331140242903

(3)方法区内存溢出

  • 1.8以前会导致永久代内存溢出
  • 1.8以后会导致元空间内存溢出

(4)常量池

二进制字节码的组成:类的基本信息、常量池、类的方法定义(包含了虚拟机指令)

通过反编译来查看类的信息

  • 获得对应类的.class文件
  • 在JDK对应的bin目录下运行cmd,也可以在IDEA控制台输入
  • 输入 javac 对应类的绝对路径
  • 输入完成后,对应的目录下就会出现类的.class文件
  • 在控制台输入 javap -v 类的绝对路径

然后能在控制台看到反编译以后类的信息了

  • 类的基本信息

image-20220331140800465

  • 常量池

image-20220331140812348

image-20220331140826328

  • 虚拟机中执行编译的方法(框内的是真正编译执行的内容,#号的内容需要在常量池中查找)

image-20220331140838277

(5)运行时常量池

  • 常量池: 就是一张表(如上图中的constant pool),虚拟机指令根据这张常量表找到要执行的类名、方法 名、参数类型、字面量信息
  • 运行时常量池:常量池是.class文件中的,当该类被加载以后,它的常量池信息就会放入运行时常量池,并把里面的 符号地址变为真实地址