pull/6/head
yuanguangxin 4 years ago
parent fc8dd0cf5f
commit ec326b5438

@ -2,9 +2,8 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="af7ffdf2-4ddc-4ed6-8222-60ed5acbc2ed" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/src/数组操作/q78_子集/Solution.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Rocket.md" beforeDir="false" afterPath="$PROJECT_DIR$/Rocket.md" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -59,6 +58,12 @@
<property name="add_unversioned_files" value="true" />
<property name="aspect.path.notification.shown" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.tslint" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="project.structure.last.edited" value="Modules" />
@ -262,14 +267,8 @@
<workItem from="1591365073366" duration="5000" />
<workItem from="1591451838662" duration="723000" />
<workItem from="1591524368167" duration="184000" />
<workItem from="1591587079718" duration="2273000" />
</task>
<task id="LOCAL-00020" summary="update q206">
<created>1581705659513</created>
<option name="number" value="00020" />
<option name="presentableId" value="LOCAL-00020" />
<option name="project" value="LOCAL" />
<updated>1581705659513</updated>
<workItem from="1591587079718" duration="3483000" />
<workItem from="1591599367868" duration="974000" />
</task>
<task id="LOCAL-00021" summary="update Rocket.md">
<created>1581851491537</created>
@ -607,7 +606,14 @@
<option name="project" value="LOCAL" />
<updated>1591337784803</updated>
</task>
<option name="localTasksCounter" value="69" />
<task id="LOCAL-00069" summary="add q78">
<created>1591590258725</created>
<option name="number" value="00069" />
<option name="presentableId" value="LOCAL-00069" />
<option name="project" value="LOCAL" />
<updated>1591590258725</updated>
</task>
<option name="localTasksCounter" value="70" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@ -660,7 +666,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="add q73/q102/q118/q224" />
<MESSAGE value="add q736" />
<MESSAGE value="增加操作系统相关问题" />
<MESSAGE value="增加JVM相关问题" />
@ -685,50 +690,51 @@
<MESSAGE value="add q62" />
<MESSAGE value="增加问题" />
<MESSAGE value="update" />
<option name="LAST_COMMIT_MESSAGE" value="update" />
<MESSAGE value="add q78" />
<option name="LAST_COMMIT_MESSAGE" value="add q78" />
</component>
<component name="WindowStateProjectService">
<state x="458" y="204" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1587221348872">
<screen x="0" y="0" width="1440" height="900" />
</state>
<state x="458" y="204" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog/0.0.1440.900@0.0.1440.900" timestamp="1587221348872" />
<state x="404" y="60" key="CommitChangelistDialog2" timestamp="1591337784627">
<state x="404" y="60" key="CommitChangelistDialog2" timestamp="1591590258488">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="303" y="50" key="CommitChangelistDialog2/0.0.1440.900@0.0.1440.900" timestamp="1588749779133" />
<state x="404" y="60" key="CommitChangelistDialog2/0.0.1920.1080@0.0.1920.1080" timestamp="1591337784627" />
<state x="404" y="60" key="CommitChangelistDialog2/0.0.1920.1080@0.0.1920.1080" timestamp="1591590258488" />
<state x="191" y="94" width="1152" height="720" key="DiffContextDialog" timestamp="1591262490778">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="143" y="78" width="1152" height="720" key="DiffContextDialog/0.0.1440.900@0.0.1440.900" timestamp="1588749770793" />
<state x="191" y="94" key="DiffContextDialog/0.0.1920.1080@0.0.1920.1080" timestamp="1591262490778" />
<state x="143" y="78" width="1152" height="720" key="DiffContextDialog/0.23.1440.797@0.23.1440.797" timestamp="1588303139733" />
<state width="1878" height="380" key="GridCell.Tab.0.bottom" timestamp="1591590079172">
<state width="1878" height="380" key="GridCell.Tab.0.bottom" timestamp="1591595634376">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1398" height="204" key="GridCell.Tab.0.bottom/0.0.1440.900@0.0.1440.900" timestamp="1587225087588" />
<state width="1878" height="380" key="GridCell.Tab.0.bottom/0.0.1920.1080@0.0.1920.1080" timestamp="1591590079172" />
<state width="1878" height="380" key="GridCell.Tab.0.bottom/0.0.1920.1080@0.0.1920.1080" timestamp="1591595634376" />
<state width="1398" height="245" key="GridCell.Tab.0.bottom/0.23.1440.797@0.23.1440.797" timestamp="1587203529573" />
<state width="1878" height="359" key="GridCell.Tab.0.bottom/0.23.1920.977@0.23.1920.977" timestamp="1591364244398" />
<state width="1878" height="380" key="GridCell.Tab.0.center" timestamp="1591590079171">
<state width="1878" height="380" key="GridCell.Tab.0.center" timestamp="1591595634219">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1398" height="204" key="GridCell.Tab.0.center/0.0.1440.900@0.0.1440.900" timestamp="1587225087587" />
<state width="1878" height="380" key="GridCell.Tab.0.center/0.0.1920.1080@0.0.1920.1080" timestamp="1591590079171" />
<state width="1878" height="380" key="GridCell.Tab.0.center/0.0.1920.1080@0.0.1920.1080" timestamp="1591595634219" />
<state width="1398" height="245" key="GridCell.Tab.0.center/0.23.1440.797@0.23.1440.797" timestamp="1587203529571" />
<state width="1878" height="359" key="GridCell.Tab.0.center/0.23.1920.977@0.23.1920.977" timestamp="1591364244398" />
<state width="1878" height="380" key="GridCell.Tab.0.left" timestamp="1591590079170">
<state width="1878" height="380" key="GridCell.Tab.0.left" timestamp="1591595634218">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1398" height="204" key="GridCell.Tab.0.left/0.0.1440.900@0.0.1440.900" timestamp="1587225087586" />
<state width="1878" height="380" key="GridCell.Tab.0.left/0.0.1920.1080@0.0.1920.1080" timestamp="1591590079170" />
<state width="1878" height="380" key="GridCell.Tab.0.left/0.0.1920.1080@0.0.1920.1080" timestamp="1591595634218" />
<state width="1398" height="245" key="GridCell.Tab.0.left/0.23.1440.797@0.23.1440.797" timestamp="1587203529570" />
<state width="1878" height="359" key="GridCell.Tab.0.left/0.23.1920.977@0.23.1920.977" timestamp="1591364244397" />
<state width="1878" height="380" key="GridCell.Tab.0.right" timestamp="1591590079171">
<state width="1878" height="380" key="GridCell.Tab.0.right" timestamp="1591595634375">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state width="1398" height="204" key="GridCell.Tab.0.right/0.0.1440.900@0.0.1440.900" timestamp="1587225087587" />
<state width="1878" height="380" key="GridCell.Tab.0.right/0.0.1920.1080@0.0.1920.1080" timestamp="1591590079171" />
<state width="1878" height="380" key="GridCell.Tab.0.right/0.0.1920.1080@0.0.1920.1080" timestamp="1591595634375" />
<state width="1398" height="245" key="GridCell.Tab.0.right/0.23.1440.797@0.23.1440.797" timestamp="1587203529572" />
<state width="1878" height="359" key="GridCell.Tab.0.right/0.23.1920.977@0.23.1920.977" timestamp="1591364244398" />
<state width="1878" height="359" key="GridCell.Tab.1.bottom" timestamp="1591364244400">
@ -763,11 +769,11 @@
<screen x="0" y="0" width="1440" height="900" />
</state>
<state x="221" y="63" key="SettingsEditor/0.0.1440.900@0.0.1440.900" timestamp="1585223890241" />
<state x="427" y="228" key="Vcs.Push.Dialog.v2" timestamp="1591337785942">
<state x="427" y="228" key="Vcs.Push.Dialog.v2" timestamp="1591590259825">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="320" y="190" key="Vcs.Push.Dialog.v2/0.0.1440.900@0.0.1440.900" timestamp="1588749781144" />
<state x="427" y="228" key="Vcs.Push.Dialog.v2/0.0.1920.1080@0.0.1920.1080" timestamp="1591337785942" />
<state x="427" y="228" key="Vcs.Push.Dialog.v2/0.0.1920.1080@0.0.1920.1080" timestamp="1591590259825" />
<state x="100" y="100" width="1240" height="700" key="com.intellij.history.integration.ui.views.FileHistoryDialog" timestamp="1587219014962">
<screen x="0" y="23" width="1440" height="797" />
</state>

@ -85,7 +85,7 @@ Redis中setnx不支持设置过期时间做分布式锁时要想避免某一
### 如何解决 Redis 缓存穿透问题
1. 在接口做校验
2. 存null值缓存击穿加锁
2. 存null值缓存击穿加锁,或设置不过期
3. 布隆过滤器拦截: 将所有可能的查询key 先映射到布隆过滤器中查询时先判断key是否存在布隆过滤器中存在才继续向下执行如果不存在则直接返回。布隆过滤器将值进行多次哈希bit存储布隆过滤器说某个元素在可能会被误判。布隆过滤器说某个元素不在那么一定不在。
### Redis的持久化机制
@ -151,22 +151,6 @@ Redis默认是快照RDB的持久化方式。对于主从同步来说主从刚
| 可重复读 | 否 | 否 | 是 |
| 串行化 | 否 | 否 | 否 |
### MVCC多版本并发控制
MVCC在RR可重复读级别解决了可能出现不可重复读的问题同时解决了读数据情况下的幻读问题对于修改新增的操作依旧存在幻读问题。它的实现原理主要是依赖记录中的 3个隐式字段undolog指针 Read View 来实现的。
#### 隐式字段
每行记录除了我们自定义的字段外,还有数据库隐式定义的最近修改(修改/插入)事务ID回滚指针指向这条记录的上一个版本隐含的自增ID隐藏主键如果数据表没有主键InnoDB会自动以DB_ROW_ID产生一个聚簇索引。
#### Read View
Read View就是事务进行快照读操作的时候生产的读视图在该事务执行的快照读的那一刻会生成数据库系统当前的一个快照记录并维护系统当前活跃事务的ID。Read View遵循一个可见性算法主要是将要被修改的数据的最新记录中的DB_TRX_ID即当前事务ID取出来与系统当前其他活跃事务的ID去对比由Read View维护如果DB_TRX_ID跟Read View的属性做了某些比较不符合可见性那就通过DB_ROLL_PTR回滚指针去取出Undo Log中的DB_TRX_ID再比较即遍历链表的DB_TRX_ID从链首到链尾即从最近的一次修改查起直到找到满足特定条件的DB_TRX_ID, 那么这个DB_TRX_ID所在的旧记录就是当前事务能看见的最新老版本。
### Next-Key Lock
InnoDB 采用 Next-Key Lock 解决幻读问题。在`insert into test(xid) values (1), (3), (5), (8), (11);`后由于xid上是有索引的该算法总是会去锁住索引记录。现在该索引可能被锁住的范围如下(-∞, 1], (1, 3], (3, 5], (5, 8], (8, 11], (11, +∞)。Session A`select * from test where id = 8 for update`)执行后会锁住的范围:(5, 8], (8, 11]。除了锁住8所在的范围还会锁住下一个范围所谓Next-Key。
### Mysql的逻辑结构
* 最上层的服务类似其他CS结构比如连接处理授权处理。
@ -181,7 +165,7 @@ SQL的执行顺序from---where--group by---having---select---order by
* undoLog 也就是我们常说的回滚日志文件 主要用于事务中执行失败进行回滚以及MVCC中对于数据历史版本的查看。由引擎层的InnoDB引擎实现,是逻辑日志,记录数据修改被修改前的值,比如"把id='B' 修改为id = 'B2' 那么undo日志就会用来存放id ='B'的记录”。当一条数据需要更新前,会先把修改前的记录存储在undolog中,如果这个修改出现异常,,则会使用undo日志来实现回滚操作,保证事务的一致性。当事务提交之后undo log并不能立马被删除,而是会被放到待清理链表中,待判断没有事物用到该版本的信息时才可以清理相应undolog。它保存了事务发生之前的数据的一个版本用于回滚同时可以提供多版本并发控制下的读MVCC也即非锁定读。
* redoLog 是重做日志文件是记录数据修改之后的值用于持久化到磁盘中。redo log包括两部分一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file)该部分日志是持久的。由引擎层的InnoDB引擎实现,是物理日志,记录的是物理数据页修改的信息,比如“某个数据页上内容发生了哪些改动”。当一条数据需要更新时,InnoDB会先将数据更新然后记录redoLog 在内存中然后找个时间将redoLog的操作执行到磁盘上的文件上。不管是否提交成功我都记录你要是回滚了那我连回滚的修改也记录。它确保了事务的持久性。每个InnoDB存储引擎至少有1个重做日志文件组group每个文件组下至少有2个重做日志文件如默认的ib_logfile0和ib_logfile1。为了得到更高的可靠性用户可以设置多个的镜像日志组mirrored log groups将不同的文件组放在不同的磁盘上以此提高重做日志的高可用性。在日志组中每个重做日志文件的大小一致并以循环写入的方式运行。InnoDB存储引擎先写重做日志文件1当达到文件的最后时会切换至重做日志文件2再当重做日志文件2也被写满时会再切换到重做日志文件1中。
* MVCC多版本并发控制是MySQL中基于乐观锁理论实现隔离级别的方式用于读已提交和可重复读取隔离级别的实现。在MySQL中会在表中每一条数据后面添加两个字段最近修改该行数据的事务ID指向该行undolog表中回滚段的指针。Read View判断行的可见性创建一个新事务时copy一份当前系统中的活跃事务列表。意思是当前不应该被本事务看到的其他事务id列表。
* MVCC多版本并发控制是MySQL中基于乐观锁理论实现隔离级别的方式用于读已提交和可重复读取隔离级别的实现。在MySQL中会在表中每一条数据后面添加两个字段最近修改该行数据的事务ID指向该行undolog表中回滚段的指针。Read View判断行的可见性创建一个新事务时copy一份当前系统中的活跃事务列表。意思是当前不应该被本事务看到的其他事务id列表。已提交读隔离级别下的事务在每次查询的开始都会生成一个独立的ReadView,而可重复读隔离级别则在第一次读的时候生成一个ReadView之后的读都复用之前的ReadView。
* binlog由Mysql的Server层实现,是逻辑日志,记录的是sql语句的原始逻辑比如"把id='B' 修改为id = B2。binlog会写入指定大小的物理文件中,是追加写入的,当前文件写满则会创建新的文件写入。 产生:事务提交的时候,一次性将事务中的sql语句,按照一定的格式记录到binlog中。用于复制和恢复在主从复制中从库利用主库上的binlog进行重播(执行日志中记录的修改逻辑),实现主从同步。业务数据不一致或者错了用binlog恢复。
### binlog和redolog的区别
@ -192,6 +176,10 @@ SQL的执行顺序from---where--group by---having---select---order by
4. binlog不是循环使用在写满或者重启之后会生成新的binlog文件redolog是循环使用。
5. binlog可以作为恢复数据使用主从复制搭建redolog作为异常宕机或者介质故障后的数据恢复使用。
### Next-Key Lock
InnoDB 采用 Next-Key Lock 解决幻读问题。在`insert into test(xid) values (1), (3), (5), (8), (11);`后由于xid上是有索引的该算法总是会去锁住索引记录。现在该索引可能被锁住的范围如下(-∞, 1], (1, 3], (3, 5], (5, 8], (8, 11], (11, +∞)。Session A`select * from test where id = 8 for update`)执行后会锁住的范围:(5, 8], (8, 11]。除了锁住8所在的范围还会锁住下一个范围所谓Next-Key。
### InnoDB的关键特性
1. 插入缓冲对于非聚集索引的插入或更新操作不是每一次直接插入到索引页中而是先判断插入的非聚集索引页是否在缓冲池中若在则直接插入若不在则先放入到一个Insert Buffer对象中。然后再以一定的频率和情况进行Insert Buffer和辅助索引页子节点的merge合并操作这时通常能将多个插入合并到一个操作中因为在一个索引页中这就大大提高了对于非聚集索引插入的性能。
@ -275,15 +263,32 @@ JVM引入动态年龄计算主要基于如下两点考虑
1. 引用计数法:引用计数法是一种简单但速度很慢的垃圾回收技术。每个对象都含有一个引用计数器,当有引用连接至对象时,引用计数加1。当引用离开作用域或被置为null时,引用计数减1。虽然管理引用计数的开销不大,但这项开销在整个程序生命周期中将持续发生。垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象引用计数为0时,就释放其占用的空间。
2. 可达性分析算法这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点从这些节点开始向下搜索搜索所走过的路径称为引用链当一个对象到GC Roots没有任何引用链相连用图论的话来说就是从GC Roots到这个对象不可达则证明此对象是不可用的。
### CMS的执行过程
1. 初始标记(STW initial mark):这个过程从垃圾回收的"根对象"开始,只扫描到能够和"根对象"直接关联的对象并作标记。所以这个过程虽然暂停了整个JVM但是很快就完成了。
2. 并发标记(Concurrent marking):这个阶段紧随初始标记阶段,在初始标记的基础上继续向下追溯标记。并发标记阶段,应用程序的线程和并发标记的线程并发执行,所以用户不会感受到停顿。
3. 并发预清理(Concurrent precleaning):并发预清理阶段仍然是并发的。在这个阶段,虚拟机查找在执行并发标记阶段新进入老年代的对象(可能会有一些对象从新生代晋升到老年代, 或者有一些对象被分配到老年代)。通过重新扫描,减少下一个阶段"重新标记"的工作因为下一个阶段会Stop The World。
4. 重新标记(STW remark)这个阶段会暂停虚拟机收集器线程扫描在CMS堆中剩余的对象。扫描从"跟对象"开始向下追溯,并处理对象关联。
5. 并发清理(Concurrent sweeping):清理垃圾对象,这个阶段收集器线程和应用程序线程并发执行。
6. 并发重置(Concurrent reset)这个阶段重置CMS收集器的数据结构状态等待下一次垃圾回收。
### G1的执行过程
1. 标记阶段:首先是初始标记(Initial-Mark),这个阶段也是停顿的(stop-the-word)并且会稍带触发一次yong GC。
2. 并发标记这个过程在整个堆中进行并且和应用程序并发运行。并发标记过程可能被yong GC中断。在并发标记阶段如果发现区域对象中的所有对象都是垃圾那个这个区域会被立即回收(图中打X)。同时,并发标记过程中,每个区域的对象活性(区域中存活对象的比例)被计算。
3. 再标记这个阶段是用来补充收集并发标记阶段产新的新垃圾。与之不同的是G1中采用了更快的算法:SATB。
4. 清理阶段:选择活性低的区域(同时考虑停顿时间)等待下次yong GC一起收集对应GC log: [GC pause (mixed)],这个过程也会有停顿(STW)。
5. 回收/完成新的yong GC清理被计算好的区域。但是有一些区域还是可能存在垃圾对象可能是这些区域中对象活性较高回收不划算也肯能是为了迎合用户设置的时间不得不舍弃一些区域的收集。
### G1和CMS的比较
1. CMS收集器是获取最短回收停顿时间为目标的收集器因为CMS工作时GC工作线程与用户线程可以并发执行以此来达到降低手机停顿时间的目的只有初始标记和重新标记会STW。但是CMS收集器对CPU资源非常敏感。在并发阶段虽然不会导致用户线程停顿但是会占用CPU资源而导致引用程序变慢总吞吐量下降。
1. CMS收集器是获取最短回收停顿时间为目标的收集器因为CMS工作时GC工作线程与用户线程可以并发执行以此来达到降低停顿时间的目的只有初始标记和重新标记会STW。但是CMS收集器对CPU资源非常敏感。在并发阶段虽然不会导致用户线程停顿但是会占用CPU资源而导致引用程序变慢总吞吐量下降。
2. CMS仅作用于老年代是基于标记清除算法所以清理的过程中会有大量的空间碎片。
3. CMS收集器无法处理浮动垃圾由于CMS并发清理阶段用户线程还在运行伴随程序的运行自热会有新的垃圾不断产生这一部分垃圾出现在标记过程之后CMS无法在本次收集中处理它们只好留待下一次GC时将其清理掉。
4. G1是一款面向服务端应用的垃圾收集器适用于多核处理器、大内存容量的服务端系统。G1能充分利用CPU、多核环境下的硬件优势使用多个CPUCPU或者CPU核心来缩短STW的停顿时间它满足短时间停顿的同时达到一个高的吞吐量。
5. 从JDK 9开始G1成为默认的垃圾回收器。当应用有以下任何一种特性时非常适合用G1Full GC持续时间太长或者太频繁对象的创建速率和存活率变动很大应用不希望停顿时间长(长于0.5s甚至1s)。
6. G1将空间划分成很多块Region然后他们各自进行回收。堆比较大的时候可以采用采用复制算法碎片化问题不严重。整体上看属于标记整理算法,局部(region之间)属于复制算法。
7. G1 需要记忆集 (具体来说是卡表)来记录新生代和老年代之间的引用关系,这种数据结构在 G1 中需要占用大量的内存,可能达到整个堆内存容量的 20% 甚至更多。而且 G1 中维护记忆集的成本较高,带来了更高的执行负载,影响效率。所以 CMS 在小内存应用上的表现要优于 G1而大内存应用上 G1 更有优势大小内存的界限是6GB到8GB。
7. G1 需要记忆集来记录新生代和老年代之间的引用关系,这种数据结构在 G1 中需要占用大量的内存,可能达到整个堆内存容量的 20% 甚至更多。而且 G1 中维护记忆集的成本较高,带来了更高的执行负载,影响效率。所以 CMS 在小内存应用上的表现要优于 G1而大内存应用上 G1 更有优势大小内存的界限是6GB到8GB。Card TableCMS中的结构是一个连续的byte[]数组扫描Card Table的时间比扫描整个老年代的代价要小很多G1也参照了这个思路不过采用了一种新的数据结构 Remembered Set 简称Rset。RSet记录了其他Region中的对象引用本Region中对象的关系属于points-into结构谁引用了我的对象。而Card Table则是一种points-out我引用了谁的对象的结构每个Card 覆盖一定范围的Heap一般为512Bytes。G1的RSet是在Card Table的基础上实现的每个Region会记录下别的Region有指向自己的指针并标记这些指针分别在哪些Card的范围内。 这个RSet其实是一个Hash TableKey是别的Region的起始地址Value是一个集合里面的元素是Card Table的Index。每个Region都有一个对应的Rset。
### 哪些对象可以作为GC Roots
@ -447,7 +452,7 @@ JVM引入动态年龄计算主要基于如下两点考虑
从GC日志中找到长时间停顿的具体日志信息(添加了-XX:+PrintReferenceGC参数) 找到的日志片段如下所示。从日志中可以看出真正执行GC动作的时间不是很长但从准 备开始GC到真正开始GC之间所消耗的时间却占了绝大部分。
除GC日志之外还观察到这个GUI程序内存变化的一个特点当它最小化的时候资源 管理中显示的占用内存大幅度减小,但是虚拟内存则没有变化,因此怀疑程序在最小化时它 的工作内存被自动交换到磁盘的页面文件之中了这样发生GC时就有可能因为恢复页面文 件的操作而导致不正常的GC停顿。在Java的GUI程序中要避免这种现象可以 加入参数“-Dsun.awt.keepWorkingSetOnMinimize=true”来解决。
除GC日志之外还观察到这个GUI程序内存变化的一个特点当它最小化的时候资源 管理中显示的占用内存大幅度减小但是虚拟内存则没有变化因此怀疑程序在最小化时它的工作内存被自动交换到磁盘的页面文件之中了这样发生GC时就有可能因为恢复页面文件的操作而导致不正常的GC停顿。在Java的GUI程序中要避免这种现象可以 加入参数“-Dsun.awt.keepWorkingSetOnMinimize=true”来解决。
## Java基础
@ -464,7 +469,7 @@ HashMap的环若当前线程此时获得ertry节点但是被线程中断
### HashMap如果我想要让自己的Object作为K应该怎么办
1. 重写hashCode()是因为需要计算存储数据的存储位置需要注意不要试图从散列码计算中排除掉一个对象的关键部分来提高性能这样虽然能更快但可能会导致更多的Hash碰撞
2. 重写equals()方法需要遵守自反性、对称性、传递性、一致性以及对于任何非null的引用值xx.equals(null)必须返回false的这几个特性目的是为了保证key在哈希表中的唯一性
2. 重写equals()方法需要遵守自反性、对称性、传递性、一致性以及对于任何非null的引用值xx.equals(null)必须返回false的这几个特性目的是为了保证key在哈希表中的唯一性Java建议重写equal方法的时候需重写hashcode的方法
### volatile
@ -503,7 +508,7 @@ AQS有两个队列同步对列和条件队列。同步队列依赖一个双
### 为什么要使用线程池
1. 减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2. 可以根据系统的承受能力,调整线程池中工作线程的数目,放置因为消耗过多的内存,而把服务器累趴下
2. 可以根据系统的承受能力,调整线程池中工作线程的数目,放置因为消耗过多的内存,而把服务器累趴下
### 核心线程池ThreadPoolExecutor内部参数

Loading…
Cancel
Save