内存&Tomcat

 

 

jvm五大内存区域(即jvm运行时数据区),描述的是类被加载时,经过解析后,存储到特定的数据区。方法区和堆是所有线程共享的,而栈和计数器是线程私有的。栈处理程序运行的问题,堆处理数据的存储问题。所以才有堆栈分离
1,方法区:
又被称为元空间,用来存储类的信息,例如:方法,方法名,返回值,常量。当它无法满足内存分配需求时,方法区会抛出OutOfMemoryError。
2,堆:
存放new出来的对象信息, 全局变量。
3,虚拟机栈:
(即局部变量和正在调用的方法) 方法被调用时会在栈中开辟一块叫栈帧的空间,方法运行在栈帧空间中。栈帧出栈后,里面的局部变量直接就从内存里清理掉了。先进后出
4,程序计数器:
指向当前线程正在执行的行号,用来保证线程切换时回到程序调用的位置。(例如:在a方法里面掉用了b方法,代码从上往下执行,执行到掉用b方法的那行时,指针会记录下这个位置,然后执行b方法里面的逻辑,b方法正常执行完或异常退出,指针都会回到a方法里面。)
5,本地方法栈:
和虚拟机栈类似,只是它描述的是为虚拟机是用到的Native方法出栈和入栈的过程(通常我们不需要了解这块,它底层是C语言实现的)。

程序计数器,虚拟机栈,本地方法区是三个区域随着线程创建而创建,线程的销毁而销毁,不在垃圾回收的范围内。垃圾回收的区域主要集中在堆与方法区中。

可达性分析算法:
主流的商业语言(Java,C#)都是通过可达性分析来判定对象是否存活的。
算法思路:通过一系列称为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何的引用链,(也就是从GC Roots到这个对象不可达),那么证明此对象是不可用的。
Java中可作为GC Roots的对象:
虚拟机栈(栈帧中的本地变量表引用的对象)
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(Native方法)引用的对象

Java 语言使用 final 关键字来定义一个常量
常量,静态变量 方法区
局部变量 栈区
成员变量 堆区
new出的对象存储堆中,””存储常量池中,基本类型字面量为常量或静态变量时,存储在常量池
常量就是 程序运行中 不可以改变的量(数据) 变量就是 程序运行中 可以改变的量(数据)

 


jvm内存分类
1,方法区
方法区用来存储被虚拟机加载的类信息、静态常量、编译器编译后的代码等数据,方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量,这个区域是所有线程共享的区域,因此,它被设计成为线程安全的,final修饰不可修改

2,堆
堆是虚拟机启动的时候创建的被所有线程共享的区域。这块区域主要用来存放对象的实例,通过new操作创建出来的对象的实例都存储在堆空间中,从JDK1.7开始,字符串常量池已经被移到堆区了

3,虚拟机栈
每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用,栈与线程拥有相同的生命周期,当进行方法调用时,通过压栈与弹栈操作进行栈空间的分配与释放。当一个方法被调用的时候,会压入一个新的栈帧到这个线程的栈中,当方法调用结束后,就会弹出这个栈帧,从而回收掉调用这个方法用的栈空间。

静态常量:对于该类的对象来说,都只有一个,叫类变量
非静态常量:每个该类的对象都各有一个,叫成员变量.
1,在创建对象的时候,需要每个成员变量(非静态)开辟内存空间,类变量(静态变量)则是在类加载的时候就创建好了.
2,用static修饰过的常量会存到常量池里面。存入的方式是:先到常量池里面寻找,看是否该常量已经存在,如果存在返回该常量的引用,不存在就在常量池里面新建一个常量
3,如果没有static修饰,就属于对象的属性,绝大多是对象是存在堆中,也就是如果多个对象存在同样一个常量,在堆中会为每一个对象的该常量分配存储空间。由此可以看出,static修饰后的作用就是减少内存的消耗,常量的存储位置发生了变化

 

posted @ 2021-07-11 21:01  XUMT111  阅读(39)  评论(0编辑  收藏  举报