展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

本地方法栈、java堆、方法区、运行时常量池

本地方法栈

  • 简介
⽤于作⽤域本地⽅法执⾏的⼀块Java内存区域
  • 本地方法就是native方法
import java.util.concurrent.atomic.AtomicInteger;

public class A {

 public native static void c();

 public static void a(){
   System.out.println("enter method a");
 }

 public static void b(){
   a();
   System.out.println("enter method b");
 }

 public static void main(String[] args) {
   b();
   System.out.println("enter method main");
   AtomicInteger atomicInteger = new AtomicInteger(1);
   atomicInteger.compareAndSet(1,2);
 }

}
  • 作用
与Java虚拟机栈相同,每个⽅法在执⾏的同时都会创建⼀个栈帧(Stack Framel)⽤于存储局部变量表、操作数栈、动态链接、⽅法出⼝等信息。
每⼀个⽅法从调⽤直⾄执⾏完成的过程,就对应着⼀个栈帧在虚拟机栈中⼊栈到出栈的过程
  • 特点
Hotshot将Java虚拟机栈和本地⽅法栈合⼆为⼀
Hotshot只是jvm的一种实现

java堆

  • 简介
是Java内存区域中⼀块⽤来存放对象实例的区域,【⼏乎所有的对象实例都在这⾥分配内存】
  • 作用
此内存区域的唯⼀⽬的就是存放对象实例
Java 堆(Java Heap)是 Java 虚拟机所管理的内存中最⼤的⼀块 Java 堆是被所有线程共享的⼀块内存区域
  • 特点
Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆”(Garbage)
可配置 -Xmx -Xms
Java堆可以分成新⽣代和⽼年代,新⽣代可分为 To Space、From Space、Eden
  • 案例
任意启动1个java项目
cmd中输入 ps -eflgrep java
查看到当前应用的进程pid
sudo jmap -heap pid
查看java堆

方法区

  • 简介
是各个线程共享的内存区域,它⽤于存储已被虚拟机加载的类信息、常量、静态变量、即时
编译器编译后的代码等数据
什么是类信息:类版本号、⽅法、接⼝
  • 作用
内存中存放类信息、静态变量等数据,属于线程共享的⼀块区域
Hotspot使⽤永久代来实现⽅法区 JRockit、IBM J9VM Java堆⼀样管理这部分内存
  • 特点
并⾮数据进⼊了⽅法区就如永久代的名字⼀样“永久”存在了。这区域的内存回收⽬标主要是针对常量池的回收和对类型的卸载
⽅法区也会抛出OutofMemoryError,当它⽆法满⾜内存分配需求时

运行时常量池

  • 简介
运⾏时常量池是⽅法区的⼀部分,Class⽂件除了有类的版本、字段、⽅法、接⼝等描述信息外,还有⼀项信息是常量池,⽤于存放编译器⽣成的各种字⾯量和符号引⽤,这部分内容将在类加载后进⼊⽅法区的运⾏时常量池中存放。
  • 运⾏时常量池的模拟
public class A {
 public static void main(String[] args) {
 String a = "abc";
 String b = "abc";
 System.out.println(a==b);
 String c = new String("abc");
 System.out.println(a==c);
 System.out.println(a==c.intern());
 }
}

# 控制台打印结果
true
false
true
  • 分析

  • 第1个true是因为栈中a和b指向运行时常量池

  • 第2个为false,是因为a指向运行时常量池,c指向堆

  • 第3个为true,是因为intern方法将c移动到运行时常量池

  • 特点

运⾏时常量池是⽅法区的⼀部分,受到⽅法区内存的限制,当常量池再申请到内存时会抛出OutOfMemoryError异常
posted @ 2022-09-15 09:10  DogLeftover  阅读(50)  评论(0编辑  收藏  举报