概述
首先讲JVM的基本信息
1) 作者站在内存的角度讲了Java以及JVM在内存管理方面的问题,其中重点讲解Java虚拟机在执行Java程序的过程中将内存划分为五个数据区
介绍了五大内存域
1) 程序计数器:负责选取下一条需要执行的字节码指令,方便线程切换后恢复原来状态 ,因为这个原因需要保证各线程之间互补干扰——线程私有内存。另外,正在执行本地方法时,程序计数器为空,是唯一没规定任何OOM(Out of MemoryError)情况的区域
2) Java虚拟机栈:负责存放局部变量表【基本数据类型、句柄(引用变量)/引用指针】、方法调用时形成的栈帧方法1{调用方法2[调用方法3]}...
栈满会出现StackoverflowError,部分虚拟机会动态扩展扩容,申请不到时出现OOM
- 问:全局变量存在哪?答:全局变量不是存储在栈中的,而是存储在方法区中的,因为它是“某个类的成员”/成员变量。
- 问: final修饰的变量放哪?答:暂未
- 问: static final 修饰的变量呢?答:暂未
栈的内存管理也是jvm管理的,只是不是gc而已。栈的管理是因为栈本身数据结构的特性,在函数执行完后,不用的数据自动会出栈的,释放出空间。
当然在栈中有共享池/常量池概念如下解释说明
String
- -Xss:猜测全称是eXtended ,Stack ,Size。规定了每个线程虚拟机栈及堆栈的大小,一般情况下,256k是足够的,此配置将会影响此进程中并发线程数的大小。
- java实现的swap交换没效果的很可能原因:是调用swap时,调用swap生成栈帧里拷贝了一份新的变量,跟传入时的变量已经脱轨了
3) 堆:所有线程共享、存放所有对象实例以及数组【句柄都在栈中,而数组句柄指向堆中数组的首地址,句柄(引用变量)跟堆对应对象/数组链接后也叫做存放在堆内存中的数组的别名】。
堆内存不够时,会先扩展。若无法扩展,JVM则OOM。
- 创建一个句柄Person;并不是对象,且存放在Java虚拟机栈中,未连接任何东西要进行初始化,当句柄跟堆内存的对象失去联系时变成了垃圾。
Java堆是垃圾收集器管理的内存区域【GC算法】,Java堆可以在物理存储上是不连续的,逻辑上是连续的。数组大部分被设计成连续内存
- -Xms:猜测全称是 eXtended Memory Size , 可扩展的内存大小 。一旦对象容量超过了JAVA堆的初始容量,JAVA堆将会自动扩容到-Xmx大小。
- -Xmx:猜测全称是 eXtended Memory Max size ,最大可分配内存。虽然说堆内存扩容,在很多情况下,通常将-Xms和-Xmx设置成一样的,因为当堆不够用而发生扩容时,会发生内存抖动影响程序运行时的稳定性。
- 怎么去理解堆共享呢?还记得java内部不同方法运行时可以使用同一个对象进行操作吗?,即就是引用类型,支持在堆里面使用同个数据。如果是栈内部的数据类型传参后修改不是同一个,即没法访问别的栈里面的数据,典型的swap交换实现。【本人参阅资料后总结,以及上面所写的内容】
- 刚好去面试碰到这样的面试题:String str = new String("abc");创建了几个对象? 并且 abc 字符串之前没有用过。这毫无疑问创建了两个对象,一个是new String 创建的一个新的对象,一个是常量“abc”对象的内容创建出的一个新的String对象,
4) 方法区:采用的是元空间技术【从JVM内存中移到计算机内存中】,且各个线程共享。
主要负责存储加载类信息(接口信息、字段信息、方法信息、类名)、静态成员变量、常量【问号点???!】
若方法区满了,会抛出OOM异常
- 在1.7以后,HotSpot【我们平时用的JVM】字符串常量池从方法区移到了堆内存中,并且可以被垃圾收集器回收,这个改动降低了字符串常量池OOM的风险。而在《深入理解Java虚拟机》中并未说从方法区移至堆中。
- 常量池还包括整数包装类型-128到127【终于找到这个点的原理 ~ 叹气】
Integer
5) 本地方法栈:只要调用方法一般用栈,负责本地方法的调用【Java调用C/python】。跟上面的Java虚拟机栈内容相似,栈满都会出现StackOverflowError
下面开始介绍运行常量池、直接内存
首先介绍了运行时常量池【跟HotSpot要区分开来】,他是方法区的一部分
1) 运行时常量池包括Class常量池。用满且无法申请抛出OOM
String
2) 直接内存也叫堆外内存【物理机内存】,是基于NIO【引入了一种基于通道与缓冲区的IO】,通过使用Native函数直接分配堆外内存,然后通过DirectByteBuffer对象作为**这块内存的引用**进行操作且该对象放堆里面,避免Java堆跟Native堆来回复制数据。【JVM虚拟机也就Java堆能够存储对象数据,想要其他地方能够存储数据则需要在本地扩展】
- 不受堆的内存大小限制,但受物理机总内存限制
谈谈HotSpot
也就是了解大概普遍虚拟机的模型后,书本在此将针对Hotspot进行展开!!!!爷青回
附录
注意点:不同版本的JVM虚拟机结构不一致,而深入理解Java虚拟机是站在大多数且官方规范来讲解;所以有些知识点在现实跟书本有点差距,特别是HotSpot这个比较活跃、爱出风头、使用量大且改动性大。可能阅读书籍跟博客时会出现很多问号???不慌!!!
- JAVA 堆栈 堆 方法区 静态区 final static 内存分配 详解(转)
- Java 内存管理(堆和栈)及 垃圾回收算法
- JVM参数调优总结 -Xms -Xmx -Xmn -Xss
- Java 堆内存是线程共享的!面试官:你确定吗?
- jvm堆和栈的问题?
- 牛客网Java刷题知识点之全局变量(又称成员变量,分为类变量和实例变量)、局部变量、静态变量(又称为类变量) - 大数据和AI躺过的坑 - 博客园
- int a = 1,到底存在于JVM的哪里
- Java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配_leunging的博客-CSDN博客_java实例变量存放在栈还是堆
- JAVA堆外内存的简介和使用
- 堆内内存与堆外内存 - wellDoneGaben - 博客园
补充知识点
1) 用Java命令看编译后的字节码文件各个区域的情况
public
具体windows 命令行操作如下,可以看到一个大致Class常量池的情况
2) 另外常量池的存储信息
最后
以上就是等待星星为你收集整理的java全局变量_《深入理解Java虚拟机》第二章的全部内容,希望文章能够帮你解决java全局变量_《深入理解Java虚拟机》第二章所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复