深入理解Java虚拟机总结一自动内存管理机制(一)

 2019-12-22 10:27  阅读(795)
文章分类:JVM

深入理解Java虚拟机总结一自动内存管理机制(一)

  • Java虚拟机运行时数据区域
  • HotSpot虚拟机对象探秘

Java虚拟机运行时数据区域

概括:

  • Java有Java编译器和Java虚拟机,编译器将Java源代码转换为.class文件,虚拟机加载并运行.class文件。Java 的开发遵循“一次编写到处乱跑”理念,它运行在 VM(虚拟机)上。

JVM启动流程:
201912000143\_1.png
JVM体系结构:
201912000143\_2.png
更详细的结构: (图片来源以及详细解释)
201912000143\_3.png

  • 运行时数据区:经过编译生成的字节码文件(class文件),由 class loader(类加载子系统)加载后交给执行引擎执行。在执行引擎执行的过程中产生的数据会存储在一块内存区域。这块内存区域就是运行时区域。

201912000143\_4.png
划分线程共享和线程独占和线程共享的原因:
201912000143\_5.png

接下来就是各个运行时数据区的详细概况:
  • (一) 程序计数器:

201912000143\_6.png

  • (二) Java虚拟机栈

201912000143\_7.png
201912000143\_8.png
201912000143\_9.png
201912000143\_10.png

  • (三) 本地方法栈

201912000143\_11.png

  • (四) Java堆

201912000143\_12.png
201912000143\_13.png

  • (五) 方法区

201912000143\_14.png
201912000143\_15.png
201912000143\_16.png
关于元空间: 元空间的本质和永久代类似,都是对JVM规范中方法区的实现,不过元空间和永久代之间最大的差别在于: 元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

  • (六)方法区中的常量池:

201912000143\_17.png

public class StringTest {

        public static void main(String[] args) {
            String s1 = "abc";  //字节码常量
            String s2 = "abc";

            System.out.println(s1 == s2); // true

            String s3 = new String("abc"); //false

            System.out.println(s1 == s3);

            System.out.println(s1 == s3.intern()); //true 运行时常量

        }
    }

上面的代码的内存分配如下:
201912000143\_18.png

  • (七) 直接内存(不是运行时数据区域的一部分):

201912000143\_19.png

HotSpot虚拟机对象探秘

  • 对象的创建过程
  • 对象的内存布局(结构)
  • 对象的访问定位

对象的创建过程

1). 对象的内存分配

201912000143\_20.png

虚拟机在堆中分配内存有两种方式:

  • 指针碰撞
    201912000143\_21.png
  • 空闲列表
    201912000143\_22.png
2). 线程安全问题

201912000143\_23.png

3). 初始化对象

201912000143\_24.png

5). 调用对象的构造方法< init >

201912000143\_25.png

对象的内存布局(结构)

201912000143\_26.png

对象的访问定位

  • 句柄访问
  • 直接指针

句柄访问:
201912000143\_27.png
直接指针:
201912000143\_28.png
各自的优势:
201912000143\_29.png

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 深入理解Java虚拟机总结一自动内存管理机制(一)

相关推荐