了解内容
class文件
class文件包含了java程序执行的字节码;
数据按照格式紧凑的排列在class文件中的二进制流 ,中间无任何分割符;
文件 开头 有一个 16进制特色的标志(0x ca fe ba be)
复杂的文件格式并不是给程序员看的 ,而是专门给JVM 看,人可以借助工具查看.
经过不同的JVM解析 , 转换为具体平台上的机器指令实现跨平台
class内容
线程角度看内存图的介绍
方法区
JVM用来存储加载的类信息,
常量,静态变量,编译后的代码等数据.
每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享.
堆内存
可以细分为:
老年代 ,新生代
JVM启动时创建,存放对象的实例.
这里涉及 垃圾回收器
虚拟机栈
用于执行java方法 设立的
每个线程都在这个空间有一个私有的空间.
线程栈=栈帧+栈帧+栈帧+栈帧+栈帧+…
一个线程会执行一个/多个方法 ,一个方法对应一个栈帧
栈帧包含:局部变量,操作数栈 ,动态链接 ,方法返回地址,附加信息等
栈内存默认最大是1M,超出 抛出异常
StackOverflowError 堆 溢出 错误
本地方法栈
和虚拟栈类似 .
HotSpot虚拟机中 虚拟机栈和本地方法栈 是一样的
用于为虚拟机使用Native 本地方法 而设立的
Native:本地的,天然的
程序计数器
具有寄存信息和计数两种功能的结构
程序计数器是计算机处理器中的寄存器,
它包含当前正在执行的字节码指令的地址(位置)。
当每个指令被获取,程序计数器的存储地址加一。
在每个指令被获取之后,程序计数器指向顺序中的下一个指令。
当计算机重启或复位时,程序计数器通常恢复到 零。
串讲程序完整运行分析
.class字节码 首先加载到
1.方法区(共享的)
包含:
- 类信息 ,
- 运行时常量池,字符串常量
2.运行代码在 线程 独占的空间
JVM 创建线程 来执行代码 , 在
- 虚拟机栈 多个栈帧
- 程序计数器 指令执行位置:字节码指令地址 ,多个地址
内存 区创建线程独占的空间
JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。
栈是系统数据结构,对于进程/线程是唯一的;
堆是函数库内部数据结构,不一定唯一。
不同堆分配的内存无法互相操作。不共享
栈空间分静态分配和动态分配两种。
堆 只支持动态分配
静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloca函数完成。
看第一步吧500压入操作栈,计数器为0
第二步如图:吧操作栈内容 写入本地栈
如图:100插入操作栈 ,
这个过程可以叫做 加载 ,保存值的过程
运算的,我们看码表 来知道 下一步到底什么意思
先把数取出 ,然后 运算 吧结果存到操作栈 ,在吧5 保存到本地变量表
方法调用
java内存知识点
Main函数就是栈的 起始点
堆 是所以线程共享的: 存储的单位
栈 和线程对应 是独立的 :程序执行,数据处理
在 堆 中分配的内存,由Java虚拟机的 自动垃圾回收器(CG)来管理。
在 栈 中分配的内存 自动释放,空间有限
Object a=null;只在栈中分配内存。
new Object();在堆中分配空间。
Object b =new Object();在栈中分配空间,指向堆中的地址。
把内存分为 堆栈 的意义何在?
1.从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。分而治之的思想。
这种隔离、模块化的思想在软件设计的方方面面都有体现。
2.堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。
好处:
a.提供 了一种有效的数据交互方式(如:共享内存)
b.堆中的共享常量和缓存可以被所有栈访问,节省了空间。
3.栈因为运行时的需要,比如保存系统运行的上下文,需要进行地址段的划分。
由于栈只能向上增长,因此就会限制住栈存储内容的能力,
而堆不同,堆中的对象是可以根据需要动态增长的,
因此栈和堆的拆分使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。
4.面向对象就是堆和栈的完美结合。
其实,面向对象方式的程序与以前结构化的程序在执行上没有任何区别。
但是,面向对象的引入,使得对待问题的思考方式发生了改变,而更接近于自然方式的思考。
当我们把对象拆开,你会发现,对象的属性其实就是数据,存放在堆中:
而对象的行为(方法),就是运行逻辑,放在栈中。
我们在编写对象的时候,其实就是编写了数据结构,也编写了处理数据的逻辑。
java参数传递 的 是 值 /引用
对象传递是引用值传递,原始类型数据传递是值传递
堆和栈中,栈是程序运行最根本的东西。程序运行可以没有堆,但是不能没有栈。
而堆是为栈进行数据存储服务的,堆就是一块共享的内存。
不过,正是因为堆和栈的分离的思想,才使得java的垃圾回收成为可能。
java中,栈的大小通过-Xss来设置,当栈中存储的数据比较多时,需要适当调大这个值,