说之前谈两个之前一直有疑问的地方:
反向代理和负载均衡有何区别?
反向代理
,是把一些静态资源存储在服务器上,当用户有请求的时候,就直接返回反向代理服务器上的资源给用户,而如果反向代理服务器上没有的资源,就转发给后面的负载均衡服务器
,负载均衡服务器再将请求分发给后端的web服务器。
区别就是:
反向代理服务器是需要存储资源的,让用户更快速的接收到资源。
负载均衡就是,为了保证后端web服务器的高可用,高并发,是不需要要存储资源,只需要转发用户的请求。
使用本地缓存
的场景
在程序中,有些表数据,数据很少,但是程序加载的时候要马上访问,并且访问的很频繁,比如(例如系统配置参数,区域信息),
针对这种情况,将数据放到程序的本地缓存中即内存中,从而提升系统的访问效率,减少数据库访问,数据库访问要占用数据库连接,同时网络消耗比较大,但同时要注意,缓存的占用空间、缓存的失效策略。
跨平台的Java运行环境—JVM
不同平台有不同的Java虚拟机,但是不同Java虚拟机所识别的是统一格式的中间代码,也就是我们常说的Java Byte Code
(Java字节码),如下图所示:
从上图可以看到从源码到Java字节码再到具体不同平台JVM执行的过程。
垃圾回收与内存堆布局
Hotspot JVM 划分
虚拟机中的共划分为三个代:年轻代
(Young Generation)、老年代
(Old Generation)和持久代
(Permanent Generation)。
其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。
内存泄漏 vs 内存溢出
内存溢出
out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露
memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
Java并发编程的类,接口和方法
线程池
在Java中,我们主要使用的线程池就是ThreadPoolExecutor
,此外还有定时的线程池ScheduledThreadPoolExecutor
。
需要注意的是对于Executors.newCachedThreadPool()方法返回的线程池的使用,该方法返回的线程池是没有线程上限的,在使用时一定要当心,因为没有办法控制总体的线程数量,而每个线程都是消耗内存的,这可能会导致过多的内存被占用。
建议尽量不要用这个方法返回的线程池,而要使用有固定线程上限的线程池。
ExecutorService——shutdown方法和awaitTermination方法
ExecutorService的关闭
shutdown和awaitTermination为接口ExecutorService定义的两个方法,一般情况配合使用来关闭线程池。
方法简介
shutdown方法
:平滑的关闭ExecutorService,当此方法被调用时,ExecutorService停止接收新的任务并且等待已经提交的任务(包含提交正在执行和提交未执行)执行完成。当所有提交任务执行完毕,线程池即被关闭。
awaitTermination方法
:接收人timeout和TimeUnit两个参数,用于设定超时时间及单位。当等待超过设定时间时,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。一般情况下会和shutdown方法组合使用。
具体实例
service.shutdown();
while (!service.awaitTermination(1, TimeUnit.SECONDS)) {
System.out.println("线程池没有关闭");
}
System