零碎笔记(五)

来源:互联网 发布:侠义英雄坐骑进阶数据 编辑:程序博客网 时间:2024/06/06 02:27
       Java内存泄露引起原因,内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费称为内存泄露。导致Java内存泄露一个场景:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收。

       对于语句String s = new String("XYZ") + new String("XYZ");
       JVM先在String池中创建一个String对象存储"XYZ",然后由于遇到new关键字,再在内存上创建一个String对象存储"XYZ";由于String池中已经有了"XYZ"的对象,所以第二个new语句不会在String池中创建对象,而只会在内存上创建一个String对象;最后两个字符串相加会在String池中创建一个String对象"XYZXYZ",并将其引用传给s。
       所以总共会创建4个String对象。

       java.util.concurrent.locks.Lock是Java 5以后引入的新的API,和synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点:Lock有比synchronized更精确的线程语义和更好的性能,而且不强制性的要求 一定要获得锁。synchronized会自动释放锁,而Lock一定要求手工释放,并且最好在finally块中释放。

protobuf-java-format可以实现Protobuf与JSON互相转换:
//protobuf转jsonMessage someProto = SomeProto.getDefaultInstance();  String jsonFormat = JsonFormat.printToString(someProto);
//json转protobufMessage.Builder builder = SomeProto.newBuilder();  String jsonFormat = load json from source;  JsonFormat.merge(jsonFormat, builder);

线程池的关闭
       可以通过调用线程池的shutdown或shutdownNow方法来关闭线程池,但是它们的实现原理不同。
        shutdow():当线程池调用该方法时,线程池的状态设置成SHUTDOWN状态,然后中断所有没有正在执行任务的线程。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。
       shutdownNow():首先将线程池的状态设置成STOP状态,然后尝试停止所有的正在执行或暂停任务的线程,不再处理还在池队列中等待的任务,并返回等待执行任务的列表。
       只要调用了上两个关闭方法的其中一个,isShutdown方法就会返回true。当所有的任务都已关闭后,才表示线程池关闭成功,这时调用 isTerminaed方法会返回true。至于应该调用哪一种方法来关闭线程池,应该由提交到线程池的任务特性决定,通常调用shutdown来关闭线程池,如果任务不一定要执行完,则可以调用shutdownNow。

线程池的监控
       通过线程池提供的参数可以对线程池进行监控。线程池里有一些属性在监控线程池的时候可以使用:
       taskCount:线程池需要执行的任务数量;
       completedTaskCount:线程池在运行过程中已完成的任务数量。小于或等于taskCount;
       largestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了;
       getPoolSize:线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不减;
       getActiveCount:获取活动的线程数。
       也可以通过扩展线程池进行监控。通过继承线程池并重写线程池的beforeExecute,afterExecute和terminated方法,可以在任务执行前,执行后和线程池关闭前干一些事情。如监控任务的平均执行时间,最大执行时间和最小执行时间等。这几个方法在线程池里是空方法。

       除了long型字段和double型字段外,java内存模型确保访问任意类型字段所对应的内存单元都是原子的。这包括引用其它对象的引用类型的字段。此外,volatile long和volatile double也具有原子性。(虽然java内存模型不保证non-volatile long 和 non-volatile double的原子性,当然它们在某些场合也具有原子性,non-volatile long在64位JVM,OS,CPU下具有原子性)

       hash table虽然性能上不如ConcurrentHashMap,但并不能完全被取代,两者的迭代器的一致性不同的,hash table的迭代器是强一致性的,而concurrenthashmap是弱一致的。 ConcurrentHashMap的get,clear,iterator 都是弱一致性的。

       BeanFactory被初始化的时候,并没有加载所有的单实例Bean对象,而是等到调用getBean()方法的时候才初始化相应的Bean实例对象。
       ApplicationContext被初始化的时候就已经检查所有的Bean对象并初始化,当调用getBean()方法的时候,直接可以从缓存中取出相应的Bean实例对象。
       WebApplicationContext是实现ApplicationContext接口的子类,是专门为WEB应用准备的,它允许从相对于Web根目录的路径中加载配置文件完成初始化工作。从WebApplicationContext中可以获取ServletContext引用,整个Web应用上下文对象将作为属性放置在ServletContext中,以便Web应用环境可以访问Spring上下文。

int num = 0;for (int i = 0; i < 10; i++) {    num = num++;}System.out.println(num);
运行结果显示num = 0。而改成如下方式:
int num = 0;for (int i = 0; i < 10; i++) {    num = num + 1;}System.out.println(num);
运行结果显示num =10。这是因为对于++操作,Java使用了中间缓存变量的机制,num = num++ 被解释成:
temp = num;num = num + 1;num = temp;

int a = 5;System.out.println((a < 5) ? 10.9 : 9);
运行结果显示9.0,因为Java会根据精度类型进行自动类型转换,故输出值为9.0,于10.9一样为double。
0 0
原创粉丝点击