1、如何理解垃圾回收?
垃圾回收是Java语言的一大特性,方便了编程,是以消耗性能为代价的;在Java虚拟机(JVM)中,有一个垃圾回收器,它的作用就是查找和回收没用的对象,以便让JVM更有效的使用内存;尽可能保证可用内存的使用效率,让可用内存得到高效的管理,程序员可以影响垃圾回收的执行,但是不能控制。
垃圾回收器的运行时间程序员是无法决定的,由JVM决定,运行时也是间接执行的,虽然可以通过System.gc( )来强制回收垃圾,但是在该命令执行后无法保证JVM会立即响应执行,下达命令后,会在短期内执行程序员的请求,但是JVM会在感到内存紧缺的时候去执行垃圾回收操作。
垃圾回收过于频繁会导致性能下降,过于稀疏会导致内存紧缺,但是这个问题JVM会自己控制好,不用程序员去控制,这也是Java语言的一个好处;但是有时候会在短期内使用掉大量内存,而且这些对象在短暂使用后就不用了,这时候有必要下达一条强制回收命令,以便有更多可用的物理内存。
JVM判断一块内存是否符合垃圾回收器收集的标准:
1、给对象赋了空值null,而且后面没有使用过;
2、给对象赋予了新值,即重新分配了内存空间。
2、如何理解线程安全?
线程安全就是在多线程访问时,采用了加锁机制,当一个线程访问该类的数据时,其他线程不能进行访问,直到这个线程访问完毕,其他线程才可以继续读取,不会出现数据不一致或数据污染。
如果代码所在的进程中有多个线程同时在运行,而这些线程可能会同时访问这段代码,如果每次运行的结果和单线程是一样的,而且其他的值也和预期是一样的,就是线程安全。
如:一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。 在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而Size=1; 如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 ,所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。看看ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
线程安全性不是一个非真即假的命题。比如: Vector 的方法都是同步的,并且 Vector 明确地设计为在多线程环境中工作。但是它的线程安全性是有限制的,即在某些方法之间有状态依赖(类似地,如果在迭代过程中 Vector 被其他线程修改,那么由 Vector.iterator() 返回的 iterator会抛出ConcurrentModifiicationException异常。对于 Java 类中常见的线程安全性级别,没有一种分类系统可被广泛接受,不过重要的是在编写类时尽量记录下它们的线程安全行为。
Bloch 给出了描述五类线程安全性的分类方法:不可变、线程安全、有条件线程安全、线程兼容和线程对立。
3、用户很多时,怎么对服务器进行优化?(servlet+jsp部分)
将在一段时间内不活跃的用户进行钝化,将用户对象序列化到本地磁盘,这样就缓解了内存压力;当用户再次活跃时,再活化就行了!
钝化:是将session内存中的对象持久化(序列化)(实现序列化接口)到磁盘;
活化:就是将磁盘上的对象再次恢复到session内存中
(1)钝化与活化的监听器HttpSessionActivationListener
可以通过配置文件 指定对象钝化时间 --- 对象多长时间不用被钝化
在META-INF下创建一个context.xml,内容如下:
<Context>
<!-- maxIdleSwap:session中的对象多长时间不使用就钝化 -->
<!-- directory:钝化后的对象的文件写到磁盘的哪个目录下,配置钝化的对象文件在 work/catalina/localhost/钝化文件 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="bonnie" />
</Manager>
</Context>
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("被钝化。。。");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("被活化。。。");
}
当访问指定的servlet工程时,在设置的时间到了以后,就会出现“被钝化”;然后再访问工程下的任意一个文件,就可以被活化。
被钝化到work/catalina/localhost/的文件