JVM 内存区域分布是什么样的?gc 发生在哪些部分?
2 个回答
你会等一个人三五年吗?劳拉 ## 程序计数器 代表当前线程所执行的字节码所在的行号,配合字节码解释器获取下一条需要执行的字节码指令。 代码中的分支、循环、跳转、异常处理、线程恢复都要依靠它来实现。 程序计数器是线程私有的,线程消失它就消失,每个线程维护自己的程序计数器,互不影响。 如果当前线程正在执行本地方法,此时程序计数器为空值。  ## 虚拟机栈 虚拟机栈描述的是java方法执行的线程内存模型,当方法执行的时候,Java虚拟机会创建一个栈帧用于存储局部变量表、操作数栈、动态链接和方法出口等信息,在每个方法种调用其他方法都是进出栈的操作,当方法执行完毕,栈帧被移除。   ## 本地方法栈 本地方法栈和虚拟机方法栈作用类似,不过它是为执行native方法服务 ## 堆 堆是被线程共享的一个内存区域,大部分对象都在堆上分配,少部分允许在栈上分配(通过逃逸分析)。堆中有新生代和老年代之分,目的是为了垃圾回收的更高效和更少停顿。  ## 方法区 方法区也是一块内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。也包括运行时常量池。 jdk8以前主要通过永久代实现方法区 jdk8开始 通过元空间实现方法区 通过本地内存实现  ## 直接内存 直接内存和堆内内存相对应,堆外内存就是把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是java虚拟机)。 传统BIO 访问  直接内存访问 发布于 2024-12-16 20:11 •IP属地 浙江举报评论收藏
在漆黑的夜里,你需要一道光照亮夜行的路,我燃烧了我自己,但也造就了你我不能相拥。蚂蚱Java虚拟机的内存区域主要分为虚拟机栈,本地方法栈,程序计数器,堆,方法区。垃圾回收主要是对堆中的对象进行回收,方法区里面也会进行一些垃圾回收,但是方法区中的内存回收出现的频率会比较低,主要是针对常量池的回收 和 对类型的卸载,判定一个常量是否是“废弃常量”比较简单,不被引用就行了,而要判定一个类是否是“无用的类”的条件则相对苛刻许多。类需要同时满足下面3个条件才能算是“无用的类”: 1.该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例; 2.加载该类的ClassLoader已经被回收; 3.该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法; ### 虚拟机栈 是Java方法执行的内存模型,主要是用于方法执行的,每次执行方法时就会创建一个栈帧来压入栈中,每个栈帧存储了方法调用需要的数据,例如局部变量表,操作数栈等。 局部变量表主要是存储方法的参数和创建的局部变量(基本类型或者引用类型),它的大小在编译时就固定了,方法有一个Code属性记录了需要的局部变量表的大小。 操作数栈是一个栈,主要用来做算术运算及调用其他方法时存储传参,调用其他方法时,当前方法栈帧的操作数栈会跟其他方法的局部变量表有一定的重叠,主要便于共享这些传递参数,节约内存空间。(最大深度也是编译时就计算好的。) ### 本地方法栈 线程在调用native方法时使用的栈。 ### 程序计数器 跟虚拟机栈,本地方法栈一样,程序计数器也是线程私有的,主要用来记录当前线程执行的字节码指令的行号,字节码解释器通过改变这个计数器来选取下一条需要执行的字节码指令。 ### 堆 用来存储对象和数据的区域,被所有线程共享,在物理上可以是不连续的。 ### 方法区 方法区也是被线程共享的,主要存放类型信息,常量,静态变量,方法去中有一个运行时常量池。 Java中的类在编译后会生成class文件,class文件除了包含变量,方法,接口信息外还包含一个常量池表,用于存放编译时生成的各种字面量和符号引用,在类加载后,字符流常量池会被存放在方法区中的运行时常量池中,运行期间也会可以将新的常量添加到运行时常量池,例如对String的实例调用intern方法。发布于 2022-02-21 13:14 •IP属地 安徽举报评论收藏
公众号进入网站体验更佳

