• (1) JVM内存管理:内存模型


    引子

    一段简单的代码结果引发疑问,==到底比较的是什么?equals呢?

    public static void main(String args[]){
    String s1="abc";
    String s2="abc";
    System.out.println(s1==s2);
    System.out.println(s1.equals(s2));

    String s3=new String("abc");
    System.out.println(s1==s3);
    System.out.println(s1.equals(s3));
    }


    运行结果是:

    true

    true

    false

    true

    如果等号比较的是引用的内容,那么s1==s3的结果并非预期的那样;如果等号单纯比较引用是否相等,为什么s1==s2?

    解释

    1)等号确实比较的只是单纯的引用是不是相等的;也就是这两个引用指向的是不是同一个地址

    2)equals类型仅用于类,它比较的是类中的内容是否相等

    String类型是最简单,最适合举例的类

    我们可以明白,s1,s2指向的同一个地方,但s1和s3是不同地方

    JVM内存模型

    事实上,所有的int a=3; String a="abc";它们的对象(姑且理解成内容或者值)都被存在了一个叫运行时常量池的地方

    这个地方的好处就是每当存储变量时,会检测运行时常量池中是否有和它相等的变量;如果有,就把引用直接指向那个变量

    所以上面例子中的s1和s2,是指向运行时常量池的同一块

    那么s3呢?这时它完全按照类的模式初始化,所以它的值也被存在了Java堆中

    JVM内存模型

    一、虚拟机栈

    类似于Windows中的栈,每个线程都有自己独享的栈,用来存放运行时局部所需要的东西

    String s3=new String("abc"); 其中的s3这个引用,被存在了虚拟机栈中

    二、程序计数器

    记录JVM将要运行的下一条指令(字节码形式)的地址

    Java编译的时候首先生成.java文件,也就是字节码形式

    三、本地方法栈

    在java程序运行C语言函数时会用到

    四、堆

    所有非静态对象都在此分配并保存;这个区域是所有线程公有的

    五、方法区

    所有的静态变量都保存在这里和运行时需要的常量——简单数据类型和inal类型的一些数据——运行时常量池

    内存区域特点

    1)虚拟机栈、本地方法栈、程序计数器都是线程独有的;堆和方法区是所有线程公有的

    2)JVM在做垃圾回收的时候只针对堆;方法区是从来不动的,所以又称作永久代

    3)而垃圾回收时会将堆分成两部分;年轻代和年老代

    4)除了程序计数器,其他四块都会OutofMemory

  • 相关阅读:
    java按照指定格式输出系统时间使用SimpleDateFormat方法
    java按照指定格式输出系统时间
    java打印系统时间
    java字符串截取指定下标位置的字符串
    java根据输入的字符串和字节数来截取,输出对应字节数的字符串
    java字符串根据正则表达式让单词首字母大写
    java根据#号截取字符串,使用Pattern的方法
    java数组冒泡排序
    Prometheus+Grafana监控平台搭建
    JMeter-setUp线程组实现用户先登录(跨线程中beanshell设置全局变量)
  • 原文地址:https://www.cnblogs.com/Plorde/p/12302226.html
Copyright © 2020-2023  润新知