当前位置: 首页 > wzjs >正文

随州网站建设多少钱陕西seo公司

随州网站建设多少钱,陕西seo公司,沈阳网站设计外包,做甜品网站的需求分析目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…

目录

1.内存模型

1.1.JVM内存模型的介绍

1.2.堆和栈的区别

1.3.栈的存储细节

1.4.堆的部分

1.5.程序计数器的作用

1.6.方法区的内容

1.7.字符串池

1.8.引用类型

1.9.内存泄漏与内存溢出

1.10.会出现内存溢出的结构


1.内存模型

1.1.JVM内存模型的介绍

内存模型主要分为五个部分:虚拟机栈,本地方法栈,堆,方法区(永久代或元空间),程序计数器,当然还有一部分是直接内存。

虚拟机栈:每个线程各有一个,线程独有,当执行方法(除了本地方法native修饰的方法)之前,会创建一个栈帧,栈帧里面包含局部变量表和操作数栈和动态链接和方法出口等信息,而每个栈帧就是存入栈中

本地方法栈:每个线程各有一个,线程独有,当执行本地方法时类似于虚拟机栈,一样会创建栈帧,存入对应信息

程序计数器:每个线程各有一个,线程独有,它的作用是记录当前线程下一次执行的二进制字节码指令地址,如果执行的是本地方法那么它会记录为定值(null)

:所有线程共享,堆的回收由垃圾回收机制管理,堆中主要存入对象实例信息,类信息,数组信息,堆是JVM内存中最大的一个

永久代:在jdk1.7及以前是方法区的实现,使用的是jvm内存,独立于堆,主要存入类信息,静态变量信息,符号引用等信息

元空间:在jdk1.8及以后是方法区的实现,使用的是本地内存,主要存入类信息,静态变量信息,符号引用等信息

直接内存:该内存属于操作系统,由NIO引入,操作系统和Java程序都可以进行操作,实现共享

----

常量池:属于class文件的一部分,主要存储字面量,符号引用

----

运行时常量池:属于方法区,其实就是将常量池中的符号引用替换成了直接引用,其余一样

1.2.堆和栈的区别

五个点:用途,生命周期,存储速度,存储空间,可见性

用途:栈主要存储方法返回地址,方法参数,临时变量,每次方法执行之前会创建栈帧,而堆存储对象的实例信息,类实例信息,数组信息

生命周期:栈的生命周期可见,每次方法执行完栈帧就会移除(弹出),而堆中的数据需要由垃圾回收器回收,回收时间不确定

存储速度:栈的速度更快,栈保持"先进后出"的原则,操作简单快,而堆需要对对象进行内存分配和垃圾回收,并且垃圾回收器本身运行也会损耗性能,速度慢

存储空间:栈的空间相对于堆的空间小,栈的空间小且固定,由操作系统管理,而堆的空间是jvm中最大的,由jvm管理

可见性:栈是每个线程都有的,而堆是所有线程共享的

1.3.栈的存储细节

如果执行方法时,里面创建了基本类型,那么基本类型的数据会存入栈中,如果创建了引用类型,会将地址存入栈,其实例数据存入堆中

1.4.堆的部分

堆主要分为两部分:新生代,老年代,它的比例:1:2

新生代:新生代分为两个区:伊甸园区和幸存者区,而幸存者区又平均分为S0和S1区,伊甸园区与S0与S1之间的比例:8:1:1,每次新创建的对象实例都会先存入伊甸园区,它们主要使用的垃圾回收算法是复制算法,当伊甸园区的内存使用完时,会使用可达性分析算法,标记不可存活的对象(没有被引用的对象)将存活对象复制移入S0或S1中,这个过程叫Minor GC,如果这次移入的是S0,那么下次就会将伊甸园区和S0中的对象移入S1中,循环反复,每经历一次Minor GC过程就会给对象年龄加一,直到大于等于15时,会认为该对象生命周期长,移入老年代中

细节:其实新创建的对象不会直接存入伊甸园区,如果多线程情况下同时进行存入对象(线程竞争压力大)会导致性能的损失,因此会给每个线程从伊甸园区中先申请一块TLAB区域,先将对象存入该区,如果该区内存使用完,会重写申请或直接存入伊甸园区

老年代:老年代就是存储生命周期长的对象(不经常回收的对象),主要使用的垃圾回收算法为标记清除算法或标记整理算法,看场景出发,其中老年代还包含一个大对象区

大对象区:主要存储的就是新创建的大对象比如说大数组,会直接将该对象存入大对象区中,不在存入新生代

可达性分析算法:从GC Root出发找对应引用对象,如果一个对象没有被直接引用或间接引用,那么会被标记,GC Root可以是java的核心库中的类,本地方法使用的类,还未结束的线程使用的类,使用了锁的类

标记清除算法:对没有被引用的对象进行标记,然后进行清除(不是真正的清除,而是记录其对象的起始地址和结束地址到一个地址表中,下次要添加新对象时会先从表中找,找到一个适合大小的就会进行覆盖),清除:记录地址,新对象进行覆盖,好处:速度快,缺点:内存碎片化严重(内存不连续了,本来可以存入的对象存入不了)

标记整理算法:同理进行标记,然后再对可存活对象进行整理,最后清除,好处:避免了内存碎片化问题,缺点:速度慢

复制算法:将内存空间分为两份,一份存对象from,一份为空to,当要回收时,复制可存活对象移入为空的内存空间to中(移入既整理),然后对存对象的空间from整体清除,然后名称from和to换过来

为什么会有大对象区:因为伊甸园区的内存空间本身就不大,如果你直接创建一个大于它空间的对象,会出现问题,还有就是即使没有超过伊甸园区的空间,但是其对象依旧很大,频繁的复制移动很影响性能

1.5.程序计数器的作用

简单来说:线程1执行到某个地方时,线程2抢到了执行权,那么等到线程1执行时是不是需要知道上次执行到哪里了,所以程序计数器就是记录执行到哪里的,并且每次线程都需要有一个来记录

1.6.方法区的内容

方法区主要包含:类信息,静态变量信息,运行时常量池,即时编译器的缓存数据

1.7.字符串池

在jdk1.6及以前字符串池属于永久代,jdk1.7字符串池移入堆中但是还是属于永久代的,jdk1.8及以后还是存入堆中,但是不属于元空间了(1.7以前是永久代,1.8以后是元空间)

细节:String s1 = "a";它的过程是:先去字符串池中找,看是否能找到该字符,找到了直接复用池中地址,没有找到会先在堆中创建一个String对象,jdk1.6它会将数据复制一份重新创建一个新的对象存入池中,jdk1.7会将其地址复用给池中

String s2 = new("b");同理

String s3 = "a" + "b";常量进行相加,与new("ab")基本一致

String s4 = s1 + s2;变量相加,底层使用的是new StringBuilder.append("a").append("b").toString(),如果池中存在"ab",它也不会复用,而是直接创建,如果池中不存在,而不会将新创建的对象存入池中

1.8.引用类型

引用类型:强引用,软引用,弱引用,虚引用,(终结器引用

强引用:比如new就是,只要有强引用指向对象,那么该对象永远不会被回收

软引用:如果出现内存溢出的情况,再下次GC时会对其回收

弱引用:每次进行GC过程都会进行回收

虚引用:每次进行GC过程都会进行回收

细节:这些都是对象,等级依次递减

软引用:创建一个软引用对象时你可以指定引用队列,如果不指定会导致软引用为null一个空壳,比如说出现了GC Root强引用软引用对象,导致软引用对象无法被回收,你想要其对象被回收,可以使用引用队列,简单来说就是出现了这种情况,将软引用对象存入队列中,下次GC会扫描队列进行回收,当然这是特殊情况,总结来说:软引用可以使用引用队列也可以不使用

public class SoftRefDemo {public static void main(String[] args) throws InterruptedException {// 1. 创建引用队列ReferenceQueue<Object> queue = new ReferenceQueue<>();// 2. 创建大对象(确保能被GC回收)byte[] data = new byte[10 * 1024 * 1024]; // 10MB// 3. 创建软引用并关联队列SoftReference<Object> softRef = new SoftReference<>(data, queue);// 4. 移除强引用(只保留软引用)data = null;System.out.println("GC前: ");System.out.println("  softRef.get() = " + softRef.get());System.out.println("  queue.poll()  = " + queue.poll());// 5. 强制GC(模拟内存不足)System.gc();Thread.sleep(1000); // 给GC时间System.out.println("\nGC后: ");System.out.println("  softRef.get() = " + softRef.get());System.out.println("  queue.poll()  = " + queue.poll());}
}
GC前: softRef.get() = [B@15db9742queue.poll()  = nullGC后: softRef.get() = nullqueue.poll()  = java.lang.ref.SoftReference@6d06d69c

弱引用:与软引用相同

WeakHashMap<Key, Value> map = new WeakHashMap<>();Key key = new Key();
map.put(key, new Value());// 移除强引用
key = null;System.gc();// GC后Entry自动被移除
System.out.println(map.size()); // 输出: 0

虚引用:最好的例子就是直接内存:它就是使用了虚引用,直接内存就是从操作系统中申请了一块空间来使用,因此GC是不能对其进行回收的,如果当强引用消失只剩下虚引用,那么会将虚引用对象存入引用队列中,等队列来执行本地方法释放直接内存

public class PhantomRefDemo {public static void main(String[] args) {// 1. 创建引用队列ReferenceQueue<Object> queue = new ReferenceQueue<>();// 2. 创建虚引用Object obj = new Object();PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);// 3. 模拟直接内存分配ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024 * 1024); // 1MBSystem.out.println("GC前:");System.out.println("  phantomRef.get() = " + phantomRef.get()); // nullSystem.out.println("  queue.poll()     = " + queue.poll());     // null// 4. 移除强引用(触发回收条件)obj = null;directBuffer = null; // 释放DirectByteBuffer强引用// 5. 强制GC(实际应用中会自动触发)System.gc();try { Thread.sleep(500); } catch (Exception e) {}System.out.println("\nGC后:");System.out.println("  phantomRef.get() = " + phantomRef.get()); // nullSystem.out.println("  queue.poll()     = " + queue.poll());     // 返回phantomRef对象// 6. 实际效果:DirectByteBuffer分配的1MB堆外内存已被释放}
}

终结器引用:在所有父类Object中有一个终结器方法finalize()方法,如果重写该方法,那么执行GC之前会先执行该方法,当没强引用指向了,而这个对象还重写了finalize()方法,那么会将这个终结器引用对象加入队列中,下次GC时会先由队列来执行finalize()方法,但是指定执行的队列是一个优先级不高的队列,会导致资源释放缓慢

public class ResourceHolder {// 重写finalize方法(不推荐!)@Overrideprotected void finalize() throws Throwable {releaseResources(); // 释放资源super.finalize();}
}

1.9.内存泄漏与内存溢出

内存泄漏:就是说没有被引用的对象没有被回收,导致可用内存空间减少

比如:

  • 静态集合没有释放:一直存在
  • 线程未释放:线程应该执行完了,但是没有释放
  • 事件监听:事件源都不存在了,还在监听

例子:使用对应的文件流,字节流,但是没有释放该流,就会导致内存泄漏

解决:释放流

内存溢出:就是说内存不足了

比如:

  • 一直创建新对象
  • 持久引用:集合一直添加但是没有被清除
  • 递归

例子:ThreadLocal,每个线程都有一个ThreadLocal,本质就是每个线程存在一个ThreadLocalMap对象,key(弱引用)存入的是TreadLocal的实例,value(强引用)为自己指定的Object对象,如果没有使用该TreadLocal了,也就是说没有强引用指向TreadLocalMap对象,那么其中的key就会被设置为null,那如果该线程一直不结束,导致key不能被回收,随着key为null的情况增多就会导致内存溢出

解决:使用TreadLocal.recome();

1.10.会出现内存溢出的结构

会出现该问题的内存结构:堆,栈,元空间,直接空间

http://www.dtcms.com/wzjs/497477.html

相关文章:

  • 代人做网站seo网络营销的技术
  • 大朗镇仿做网站百度公司名称
  • 地球人-一家只做信誉的网站手机怎么建网站
  • 建站公司新闻资讯百度退款客服电话
  • 企业品牌网站建设注意事项如何免费制作网站
  • 网络网站制作过程网站推广方式有哪些
  • 哪个网站可以做付费推广微信营销模式
  • 宜昌皓月建设工程有限公司网站百度网盘app官网下载
  • 济源网站建设的公司腾讯效果推广
  • 网站客服中心模板韩国最新新闻
  • 儿童网站建设外文翻译地推拉新app推广怎么做
  • 专业广州做网站公司seo技术培训海南
  • 专业的开发网站建设价格关键词竞价广告
  • 炫酷html5网站模板营销型网站的推广方法
  • css怎么做网站横向菜单杭州网站制作排名
  • 获取网站后台地址windows优化
  • 毕业设计做网站如何创建网站?
  • 个人网站租用服务器百度一下你就知道了主页
  • 免费网站app哪个最好广东seo排名
  • asp.net如何设置网站的图标百度企业号
  • 低价企业网站搭建市场营销实务
  • 黄石网站制作公司淄博seo推广
  • 动态网站与静态网站的区别谷歌关键词排名优化
  • wordpress和kong编辑器网站优化方法
  • 网站制作多少钱西安seo外包优化
  • 网站源文件修改全国31省市疫情最新消息今天
  • 90设计网站会员全站通与电商模板的区别seo优化技术厂家
  • 个人网站 组建重庆百度快照优化排名
  • bootstrap框架制作网页seo顾问服务福建
  • 呼和浩特建设厅官方网站sem广告