【java】jvm内存模型全面解析

作者: free-coder分类: 校园学习 发布时间: 2019-08-03 14:50:06 浏览:79938 次

【java】jvm内存模型全面解析

隐形的稻草人666:
总结:JVM 内存模型是什么? (1)JVM 内存模型共分为5个区:Java虚拟机栈、本地方法栈、堆、程序计数器、方法区(元空间) (2)各个区各自的作用: a.本地方法栈:用于管理本地方法的调用,里面并没有我们写的代码逻辑,其由native修饰,由 C 语言实现。 b.程序计数器:它是一块很小的内存空间,主要用来记录各个线程执行的字节码的地址,例如,分支、循环、线程恢复等都依赖于计数器。 c.方法区(Java8叫元空间):用于存放已被虚拟机加载的类信息,常量,静态变量等数据。 d.Java 虚拟机栈:用于存储局部变量表、操作数栈、动态链接、方法出口等信息。(栈里面存的是地址,实际指向的是堆里面的对象) e.堆:Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存; (3)线程私有、公有 a.线程私有:每个线程在开辟、运行的过程中会单独创建这样的一份内存,有多少个线程可能有多少个内存 Java虚拟机栈、本地方法栈、程序计数器是线程私有的 b.线程全局共享的 堆和方法区 (4)栈虽然方法运行完毕了之后被清空了,但是堆上面的还没有被清空,所以引出了GC(垃圾回收),不能立马删除,因为不知道是否还有其它的也是引用了当前的地址来访问的

【回复】建议改成内存结构分为5个取
free-coder:
7:55 p.name="liming" 这种形式声明的字符串比较特殊,会以字符串常量的形式存在方法区的常量池中,所以改成p.name = new String("liming")才对!!

【回复】然后是char数组也是对象类型,数组中的char元素才是值类型,回头看一遍发现了两处错误,实在抱歉!!
【回复】up很良心,刚觉得string那里有问题,就看到评论区做了解释,并且置顶了,投个币[doge]
【回复】jdk1.8以后字符串常量池也是在堆里了
hello_pz:
问一个文本概念上的问题。就我所查资料当中,好像并没有JVM内存模型的说法,而是有JVM内存结构和Java内存模型的说法。JVM内存结构即视频中所讲的内容,是运行时数据区域,指从结构上看JVM的内存可以分为哪些部分,是实际存在的;而Java内存模型是Java Memory Model(JMM),是主内存和工作内存那些研究内存访问一致性的东西,指从模型上看,忽略硬件设备和系统,Java语言是如何处理并发内存访问的,这是实际中不存在的概念模型。我不知道我这么理解是否正确,还想请问一下up的理解。

【回复】你说的对的 up标题应该是JVM内存结构
【回复】兄弟,你是对的,顶上去
【回复】这么尴尬的吗,没有回声……
Gannalyo:
讲的真好,我工作快10年了,看过无数次JVM资料,从来没这么明白过,明天去面试,就和面试官掰扯jvm。[胜利]

茶茶小巫:
给个建议哈,up在讲解时最好说明下是基于什么版本的jdk,比如方法区,1.7以后静态变量是放堆了,而不是方法区了

陆陆吾:
up主讲得简单易懂,牛B,投了两个币不成敬意

阿怪Penn:
这是我听过最好的课,没废话,直接切入要害

欧得无寿:
那个new Main().func1(a)是什么意思?新建实例对象并调用func1(a)吗,那不是也应该在堆里吗[难过]

就-很-奈-斯:
我们知道栈和堆是基本的数据结构,为什么内存模型里叫做系统栈? 从程序运行的角度来讲,一个完整的程序是从main方法开始,一步一步运行main里面的语句和其他方法,实际上就是以main方法开始的一系列方法调用过程。 在一个方法中调用另一个方法时,需要暂停当前方法的进行,并保存运行数据,然后开始运行这个新的方法,要是新方法里还有别的方法,以此类推。、 当这个新的方法结束后需要把该方法的数据丢进回收站。我们发现这个过程和栈太配合了,首先栈中可以存储数据,其次后进先出——后调用的函数在调运结束后先丢到垃圾桶,perfect。 所以程序的运行在内存中的体现就是,从main方法开始,遇到其他方法,将main方法的当前信息存储在某一个数据类型中,包括运行到第几行,前面有哪些数据等,开始运调用这个新方法后,如果有新方法,就把这个方法的信息压栈,调用新方法,以此类推,直到运行至某一个方法没有调用其他方法,就把这个方法的信息出栈,之后根据栈中最后一个元素的信息运行上一个方法,一次类推,直至运行玩main方法,main方法出栈后栈中为空就是程序结束。

【回复】回复 @__一切随缘 :面向对象的运行过程也是一种“函数调用”的的过程(tips:这个函数调用是个整体短语,不是函数加调用)。函数调用面向过程是字面上的函数调用,面向对象就是方法调用,某种意义上是差不多的。实际上面向对象是一种思想,整个函数运行过程是在对象调用方法中运行的,二面向过程是方法调用其他方法,所以两者的区别是关注点不同,面向对象将属性(变量)、方法(属性)都归属于对象这种抽象,是为了实现关注点于对象上,对象成了主体,然后就有了封装(对象信息私有,只能通过消息传递获取)、继承(避免重复代码,创造层级结构)和多态(接口编程等)这些有趣的性质。
【回复】这不就是面向过程了吗,面向对象 也这么理解吗
乐乐大哥哥:
请教一个问题,java中表示内存地址引用的大小是固定为32bit/4B吗?

NFR9:
看了up好几个视频了,讲的很清晰,支持

马路爱学习:
main方法存在方法区,存的是方法签名?还是方法中的所有代码?还有func1 是存在哪的呢?

java gc jvm 内存模型

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!