- [Java 内存区域详解](#java-内存区域详解) - [写在前面 (常见面试题)](#写在前面-常见面试题) - [基本问题](#基本问题) - [拓展问题](#拓展问题) - [一 概述](#一-概述) - [二 运行时数据区域](#二-运行时数据区域) - [2.1 程序计数器](#21-程序计数器) - [2.2 Java 虚拟机栈](#22-java-虚拟机栈) - [2.3 本地方法栈](#23-本地方法栈) - [2.4 堆](#24-堆) - [2.5 方法区](#25-方法区) - [2.5.1 方法区和永久代的关系](#251-方法区和永久代的关系) - [2.5.2 常用参数](#252-常用参数) - [2.5.3 为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢?](#253-为什么要将永久代-permgen-替换为元空间-metaspace-呢) - [2.6 运行时常量池](#26-运行时常量池) - [2.7 直接内存](#27-直接内存) - [三 HotSpot 虚拟机对象探秘](#三-hotspot-虚拟机对象探秘) - [3.1 对象的创建](#31-对象的创建) - [Step1:类加载检查](#step1类加载检查) - [Step2:分配内存](#step2分配内存) - [Step3:初始化零值](#step3初始化零值) - [Step4:设置对象头](#step4设置对象头) - [Step5:执行 init 方法](#step5执行-init-方法) - [3.2 对象的内存布局](#32-对象的内存布局) - [3.3 对象的访问定位](#33-对象的访问定位) - [四 重点补充内容](#四--重点补充内容) - [4.1 String 类和常量池](#41-string-类和常量池) - [4.2 String s1 = new String("abc");这句话创建了几个字符串对象?](#42-string-s1--new-stringabc这句话创建了几个字符串对象) - [4.3 8 种基本类型的包装类和常量池](#43-8-种基本类型的包装类和常量池) - [参考](#参考) # Java 内存区域详解 ## 写在前面 (常见面试题) ### 基本问题 - **介绍下 Java 内存区域(运行时数据区)** - **Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么)** - **对象的访问定位的两种方式(句柄和直接指针两种方式)** ### 拓展问题 - **String 类和常量池** - **8 种基本类型的包装类和常量池** ## 一 概述 对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像 C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会是一个非常艰巨的任务。 ## 二 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK. 1.8 和之前的版本略有不同,下面会介绍到。 **JDK 1.8 之前:**