深入理解jvm的内存区域

分析一段代码,看他的各个部分存储的位置

  1. 具体分配步骤如下
  1. 首先jvm申请一篇内存区间
  2. jvm活得内存空间后按照配置分配堆,栈,方法区空间
  3. 类加载,把class文件放入方法去区中
  4. 执行对象创建,放入堆中,对象引用放入栈中

堆:下面的图片主要是展示对象的在实际内存中的存储位置

jvm-第二节jvm的内存区域 _内存空间

jvm-第二节jvm的内存区域 _字符串_02

栈:图片主要展示栈的共享区域以及实际内存中栈里面的属性对应实际内存的位置

jvm-第二节jvm的内存区域 _内存空间_03

jvm-第二节jvm的内存区域 _字符串_04

常量池

  1. 静态常量池:字面量和符号引用
  2. 运行时常量池:每一个类或者接口常量池运行时的表现
  3. 字符串常量池:由于字符串是一个使用频率极高的常量,所以jvm为了提高效率单独开辟一片空间存储字符串

String

  1. 首先看他的结构
  2. String的不可变性事final决定的,这样做的好处不可变意味着安全,且hash不会频繁变更(因为jvm重启过程中会重新计算)
  3. String的创建以及内存分布如下
  1. String str = "abc";
  2. String str = new String("abc");
  3. 对象的形式引用字符串
  4. String str2= "ab"+ "cd"+ "ef";这种一般编译器优化,直接新创建一个字符串了
  5. 看上面这个图片,intern方法是判断字符串常量池内是否有这个字符串,因为字符串都放一起了就可以检测

内存溢出

  1. 堆溢出:申请的空间超过最大堆内存空间
  2. 栈溢出:无限递归
  3. 方法区溢出:里面的class文件占用内存超过配置;运行时常量池溢出
  4. 本机内存溢出:这个分为内存泄漏,和jvm参数maxdirectmemorySize设置本机可用直接内存大小导致溢出的问题