2019-05-06
我们知道,CPU资源是有限的,任务的处理速度与线程个数并不是线性正相关。相反,过多的线程反而会导致CPU频繁切换,处理性能下降。所以,线程池的大小一般都是综合考虑要处理任务的特点和硬件环境,来事先设置的。
当我们向固定大小的线程池中请求一个线程时,如果线程池中没有空闲资源了,这个时候线程池如何处理这个请求?是拒绝请求还是排队请求?各种处理策略又是怎么实现的呢...
阅读全文
2019-05-05
思考:如何实现浏览器的前进和后退功能?当你依次访问完一串页面a-b-c之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面b和a。当你后退到页面a,点击前进按钮,就可以重新查看页面b和c。但是,如果你后退到页面b后,点击了新的页面d,那就无法在通过前进、后退功能查看页面c了。
如何理解栈?关于“栈”,有一个非常贴切的例子,就是一摞叠在一起的盘子。放盘子的时...
阅读全文
2019-04-29
经典链表应用场景:LRU缓存淘汰算法缓存是一种提高数据读取性能技术,硬件设计和软件开发中都有应用:CPU缓存、数据库缓存、浏览器缓存等。缓存的大小有限,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留,需要缓存淘汰策略来决定,如:先进先出策略(first in first out)、最少使用策略LFU(least frequently used)、...
阅读全文
2019-04-28
在java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能。
1. Java堆溢出java堆用于储存对象实例,我们只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量到达最大堆的容量限制后产生内存溢出异常。
2. 虚拟机栈...
阅读全文
2019-04-28
在java语言中,对象访问是如何进行的?
对象访问在java语言中无处不在,是最普通的程序行为,但即使是最简单的访问,也会涉及java栈、java堆和方法区这三个最重要内存区域之间的关联关系。
Object obj = new Object();假设这句代码出现在方法体中,那Object obj这部分的语义将会反映到java栈的本地变量表中,作为一个refe...
阅读全文
2019-04-28
运行时数据区域Java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
1.程序计数器程序计数器(program counter register)是一块较小的内存空间,它的作用可以看做是当前线程所...
阅读全文
2019-04-28
Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存。
给对象分配内存对象的内存分配,往大方向上讲,就是在堆上分配,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,讲按线程优先在TLAB上分配。少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使...
阅读全文
2019-04-28
如果说收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现。
图中展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。
明确一个观点:虽然我们是在对各个收集器进行比较,但并非为了挑选一个最好的收集器出来。因为直到现在为止还没有最好的收集器出现,更加没有万能的收集器,所以我们选择的只是对具体应用最合适的收集器。
垃圾收...
阅读全文
2019-04-28
堆中几乎存放着java世界中所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象有哪些还存活着,哪些已经死去(即不可能再被任何途径使用的对象).
1.引用计数算法很多教科书判断对象是否存活的算法是:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1。任何时刻计数器都为0的对象就是不可能再被使用...
阅读全文
2019-04-28
标记——清除算法(Mark-Sweep)算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉被标记的对象。标记过程在另一篇“深入理解JVM——对象死或否”中讲述,对象标记判定对象是不是还“存活”。
主要缺点有两个。一个是效率问题,标记和清除过程的效率都不高。另外一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎...
阅读全文
上一页 1 … 11 12 13 14 15 下一页