写点什么

WORK-09- 学习笔记

用户头像
蒜泥精英
关注
发布于: 2020 年 08 月 05 日
WORK-09-学习笔记

JAVA 虚拟机

JAVA 是跨平台的语言;

JVM 屏蔽了底层系统的不同,为 JAVA 字节码文件构造了一个统一的运行环境。


类文件->类加载器

方法区 JAVA 栈

堆 程序计数寄存器

执行引擎

方法区和堆是所有线程共享的数据区;

JAVA 栈和程序计数寄存器是每个线程独享的运行期数据区

程序计数寄存器是给程序调用,记录字节码到哪一行。

NEW 的 CLASS 是在堆内的 ;

执行引擎是 LINUX 下的 X86

JAVA 编译出来的可以在执行引擎上执行;

因为不同的环境上的执行引擎不一样,将 JAVA 字节码转换成本地操作系统认识的代码执行。


Java 启动一定要跟一个类,一定要有 MAIN 方法。

JAVA 启动虚拟机,初始化环境,内存空间等;装载这个类,放到方法区,由主线程,从 MAIN 方法开始执行,当前的线程会在 JAVA 栈创建一个栈帧放在 JAVA 栈的顶部。


NEW 的过程是执行引擎来做的,所有的代码都是执行引擎来做;

装载类都是类加载器来做的,装载到方法区内做。


JAVA 字节码文件;

计算机领域的任何问题都可以通过增加一个中间层(虚拟层)来解决。

(上次是一致性 HASH 内解决)


JAVA 所有的指令由 200 个,一个字节(8 位)可以存储 256 种不同的指令信息,一个这样的字节称为字节码。


字节码的执行过程:

JAVA 字节码文件编译过程;


类加载器的双亲委托模型

加载过的类不会加载


BOOTSTRAP CLASSLOADER

PLATFORM CLASSLOADER

APPLICATION CLASSLOADER


自定义类加载器:

可以自己写类加载器,继承 CLASSLOADER


每个 JVM 都有个唯一的堆;【都在内存中】

栈 :程序的栈帧

堆: 对象存堆

方法区(特殊区域):静态变量 静态方法存这里;


JAVA 线程栈

基本类型的变量,都被每个运行这个方法的线程放入自己的栈中;


线程工作内存 & volatile

多线程的情况下,共享变量(类的成员变量、类的静态成员变量)被 volatile 修饰后,保证不同线程堆这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这个新值堆其他的线程来说是立即可见的。


JAVA 垃圾回收

JVM 来及回收就是将 JVM 堆中已经不再使用的对象清理掉;释放宝贵的内存资源;

JVM 通过一种可达性分析算法进行垃圾对象的识别;

从线程栈以及静态区中,逐层找被引用的对象,未被标记的就回收或压缩;


JVM 分代垃圾回收

新生代,

老年代,

创建一个对象再 EDEN 区,当 EDEN 区满了后,启动一次新生代的垃圾回收,把有引用的 COPY 到 FROM 区内

通常新生代得设置比老年代小很多。

JVM 垃圾回收算法,


JSTAT 是 JDK 自带得一个轻量级得小工具,主要对 JAVA

jstat -gcutil 94685 1000 10

应用时间不稳定


JMAP

JSTACK 可以查看 JVM 内的线程堆栈信息;

JVISUALVM

JAVA 代码优化

合理并谨慎使用多线程;

线程上下文切换也是消耗 CPU 资源的事情;

理论上:

启动的线程数= 【任务执行时间/(任务执行时间-IO 等待时间)】 * CPU 内核数


如果没有阻塞,那么线程数就是内核数

如果有网络阻塞,磁盘等待,那么可以多启动线程;


竞态条件与临界区

在同一程序中运行多个线程本身不会导致问题,问题在于多个线程访问


JAVA 线程安全;

允许被多个线程安全执行的代码被称为线程安全的代码;

  • 方法局部变量:局部变量不会被多个线程共享,所以基础类型的局部变量都是线程安全的;


方法局部的对象引用:

  • 某个方法中创建的对象不会逃逸出该方法,那么它就是线程安全的;


对象成员变量:

对象成员存储在堆上,如果两个线程同时更新同一个对象的同一个成员,那么这个代码就不安全了。


JAVA WEB 应用的多线程是从哪里来的?

回答: 是容器中来的;


SERVLET 是线程安全的吗?(CTO 面试题)

回答:

SERVLET 是单实例


THreadLocal

线程共享 线程私有

threadlocal 是放在堆内的;

但是每个线程都能设置自己的值,并能获取自己设置的值,

实现原理:THreadLocal 内部设置了个 map KEY 就是 线程


内存泄漏

spring MVC 的 contorller


JVM 回收原理 面试题


秒杀系统

XXX 网站的正常流程情况:

  • 并发单台,高峰期<10;

  • 吞吐量(TPS,单台)高峰期,<60

  • CPU 负载 LOAD 高峰期,<2,发部分服务器<1

  • CPU 使用率,一般只占 1 颗核,平均 60%左右

  • 服务器平均响应事件 高峰期 ,<150 ms;

  • 图片总流量带宽 1.8G (各网站总合)


高并发下的风险

  • 网络带宽耗尽

  • 服务器 LOAD 飙高,停止响应

  • 数据库瘫痪


高并发下的事故

图片过大,导致带宽耗尽,

运营推广的图片流量不能超过现有流程的 30%;


秒杀

高并发对网站性能的影响:

并发数对吞吐量的影响;

并发数对用户响应事件的影响;


高并发实例:XXX.COM 开业秒杀活动

商业需求:


技术挑战:

系统只能提升 50% 100%这样的性能;

逐步迭代,花个半年~几年,来增加几倍,几十倍;

不可能 5 天把一个几百个人维护的系统


之前提的那么多优化方案,不可能短期内搞定;


解决方案:重新在前面做个秒杀系统;


开发个新系统远远比维护一个老系统的要

什么样回报更高,做一个新的系统;

做新的系统,没有历史包袱;


8000 并发

style 服务器:LIGHTTPPD 集群:5 台;

图片服务器:NGINX 集群,5 台

静态服务器:APACHE 集群,10 台

交易服务器:JBOSS 动态集群,10 台


秒杀系统:组成

商品列表和介绍:【XXX.COM】静态集群

填写订单页面

对于秒杀来说,

商品列表和商品介绍就写成静态的页面,这样就不用对数据库操作了。


静态化:

--采用 JS 自动更新技术将动态页面转化为静态页面;

关键点 1:页面可配置,通过设置定时器,将静态页面提前生成推送到静态资源服务器;

关键点 2:秒杀商品列表/秒杀商品介绍页面,如何判断秒杀开始否?

商品 ID 从后台获取,


并发控制,防秒杀器:

设置阀门

三道阀门的设计

分布式缓冲,三个计数器;

计数器 1:限制进入秒杀界面,1000; ---所有的压力在这个界面就处理掉了,到下个界面压力就降了;

计数器 2:限制进入下单页面,100;

计数器 3:限制进入支付系统,56;


所有数据库操作全部砍掉;


应急预案:独立域名,不影响 XXX 原有业务

机动服务器:10 台

拆东墙补西墙:

壁虎断尾:

万能出错页面:


总结:

JVM 的回收机制要理解,才能更好的帮助我们完事优化程序,防止内存泄露,提高服务器性能。


秒杀系统的实现思路和方法其实并不是很多高大上的技术,但是都是能解决问题的实用的技术和思维方法,说明我们要把这些思维方法和技术深入理解,举一反三,变成潜意识的理解。


用户头像

蒜泥精英

关注

还未添加个人签名 2018.09.19 加入

还未添加个人简介

评论

发布
暂无评论
WORK-09-学习笔记