Wetts's blog

Stay Hungry, Stay Foolish.

0%

转自:https://my.oschina.net/OutOfMemory/blog/157130

在网上看到很多人对于CountDownLatch和CyclicBarrier的区别简单理解为CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用。那如果只是这么简单的话,我觉得CyclicBarrier简单命名为ResetableCountDownLatch好了,显然不是的。

我的理解是,要从他们的设计目的去看这两个类。javadoc里面的描述是这样的。

CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

可能是我的英语不够好吧, 我感觉从这个javadoc里面要准确理解他们的差异还是不容易的。我的理解是

  • CountDownLatch: 一个线程(或者多个),等待另外N个线程完成某个事情之后才能执行。
  • CyclicBarrier: N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。

这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待,而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。

CountDownLatch 是计数器, 线程完成一个就记一个, 就像报数一样, 只不过是递减的.

而CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.

1> 查看nginx相关信息

1
yum list | grep nginx

2> 发现版本很低,于是追加 nginx 的 yum 仓库,创建一个文件 /etc/yum.repos.d/nginx.repo,并将下面的内容复制进去

1
2
3
4
5
[nginx]  
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

3>

1
yum install nginx -y

转自:https://docs.mongodb.com/manual/reference/operator/update/sort/

$sort

New in version 2.4.

The $sort modifier orders the elements of an array during a $push operation.

To use the $sort modifier, it must appear with the $each modifier. You can pass an empty array [] to the $each modifier such that only the $sort modifier has an effect.

1
2
3
4
5
6
7
8
{
$push: {
<field>: {
$each: [ <value1>, <value2>, ... ],
$sort: <sort specification>
}
}
}

For :

  • To sort array elements that are not documents, or if the array elements are documents, to sort by the whole documents, specify 1 for ascending or -1 for descending.
  • If the array elements are documents, to sort by a field in the documents, specify a sort document with the field and the direction, i.e. { field: 1 } or { field: -1 }. Do not reference the containing array field in the sort specification (e.g. { “arrayField.field”: 1 } is incorrect).

Behavior

Changed in version 2.6.

The $sort modifier can sort array elements that are not documents. In previous versions, the $sort modifier required the array elements be documents.

If the array elements are documents, the modifier can sort by either the whole document or by a specific field in the documents. In previous versions, the $sort modifier can only sort by a specific field in the documents.

Trying to use the $sort modifier without the $each modifier results in an error. The $sort no longer requires the $slice modifier. For a list of modifiers available for $push, see Modifiers.

Examples

Sort Array of Documents by a Field in the Documents

A collection students contains the following document:

1
2
3
4
5
6
7
{
"_id": 1,
"quizzes": [
{ "id" : 1, "score" : 6 },
{ "id" : 2, "score" : 9 }
]
}

The following update appends additional documents to the quizzes array and then sorts all the elements of the array by the ascending score field:

1
2
3
4
5
6
7
8
9
10
11
db.students.update(
{ _id: 1 },
{
$push: {
quizzes: {
$each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ],
$sort: { score: 1 }
}
}
}
)

The sort document refers directly to the field in the documents and does not reference the containing array field quizzes; i.e. { score: 1 } and not { “quizzes.score”: 1}

After the update, the array elements are in order of ascending score field.:

1
2
3
4
5
6
7
8
9
10
{
"_id" : 1,
"quizzes" : [
{ "id" : 1, "score" : 6 },
{ "id" : 5, "score" : 6 },
{ "id" : 4, "score" : 7 },
{ "id" : 3, "score" : 8 },
{ "id" : 2, "score" : 9 }
]
}

Sort Array Elements That Are Not Documents

A collection students contains the following document:

1
{ "_id" : 2, "tests" : [  89,  70,  89,  50 ] }

The following operation adds two more elements to the scores array and sorts the elements:

1
2
3
4
db.students.update(
{ _id: 2 },
{ $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } }
)

The updated document has the elements of the scores array in ascending order:

1
{ "_id" : 2, "tests" : [  40,  50,  60,  70,  89,  89 ] }

Update Array Using Sort Only

A collection students contains the following document:

1
{ "_id" : 3, "tests" : [  89,  70,  100,  20 ] }

To update the tests field to sort its elements in descending order, specify the { $sort: -1 } and specify an empty array [] for the $each modifier, as in the following:

1
2
3
4
db.students.update(
{ _id: 3 },
{ $push: { tests: { $each: [ ], $sort: -1 } } }
)

The result of the operation is to update the scores field to sort its elements in descending order:

1
{ "_id" : 3, "tests" : [ 100,  89,  70,  20 ] }

Use $sort with Other $push Modifiers

A collection students has the following document:

1
2
3
4
5
6
7
8
9
{
"_id" : 5,
"quizzes" : [
{ "wk": 1, "score" : 10 },
{ "wk": 2, "score" : 8 },
{ "wk": 3, "score" : 5 },
{ "wk": 4, "score" : 6 }
]
}

The following $push operation uses:

  • the $each modifier to add multiple documents to the quizzes array,
  • the $sort modifier to sort all the elements of the modified quizzes array by the score field in descending order, and
  • the $slice modifier to keep only the first three sorted elements of the quizzes array.
1
2
3
4
5
6
7
8
9
10
11
12
db.students.update(
{ _id: 5 },
{
$push: {
quizzes: {
$each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
$sort: { score: -1 },
$slice: 3
}
}
}
)

The result of the operation is keep only the three highest scoring quizzes:

1
2
3
4
5
6
7
8
{
"_id" : 5,
"quizzes" : [
{ "wk" : 1, "score" : 10 },
{ "wk" : 2, "score" : 8 },
{ "wk" : 5, "score" : 8 }
]
}

mybatis 自动生成代码

在 “Command line” 选项中输入“mybatis-generator:generate -e”

这里加了“-e ”选项是为了让该插件输出详细信息,这样可以帮助我们定位问题。

阅读全文 »

转自:http://elf8848.iteye.com/blog/378805

常见的Java内存溢出有以下三种:

java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆)溢出

JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。

可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation 和Tenured Generaion 之和。

在JVM中如果98%的时间是用于GC,且可用的Heap size 不足2%的时候将抛出此异常信息。

解决方法:手动设置JVM Heap(堆)的大小。

java.lang.OutOfMemoryError: PermGen space —- PermGen space溢出。

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。

为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,sun的 GC不会在主程序运行期对PermGen space进行清理,所以如果你的APP会载入很多CLASS的话,就很可能出现PermGen space溢出。

解决方法: 手动设置MaxPermSize大小

java.lang.StackOverflowError —- 栈溢出

栈溢出了,JVM依然是采用栈式的虚拟机,这个和C和Pascal都是一样的。函数的调用过程都体现在堆栈和退栈上了。
调用构造函数的 “层”太多了,以致于把栈区溢出了。

通常来讲,一般栈区远远小于堆区的,因为函数调用过程往往不会多于上千层,而即便每个函数调用需要 1K的空间(这个大约相当于在一个C函数内声明了256个int类型的变量),那么栈区也不过是需要1MB的空间。通常栈的大小是1-2MB的。

通常递归也不要递归的层次过多,很容易溢出。

解决方法:修改程序。

解决方法

在生产环境中tomcat内存设置不好很容易出现jvm内存溢出。

linux下的tomcat:

修改TOMCAT_HOME/bin/catalina.sh位置cygwin=false前。JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m"

如果tomcat 5 注册成了windows服务,以services方式启动的,则需要修改注册表中的相应键值。

修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Tomcat Service Manager\Tomcat5\Parameters\Java,右侧的Options原值为-Dcatalina.home="C:\ApacheGroup\Tomcat 5.0" -Djava.endorsed.dirs="C:\ApacheGroup\Tomcat 5.0\common\endorsed" -Xrs加入-Xms256m -Xmx512m,重起tomcat服务,设置生效。

如果tomcat 6 注册成了windows服务,或者windows2003下用tomcat的安装版

/bin/tomcat6w.exe里修改就可以了。

如果要在myeclipse中启动tomcat,上述的修改就不起作用了,可如下设置:

Myeclipse->preferences->myeclipse->servers->tomcat->tomcat×.×->JDK面板中的Optional Java VM arguments中添加:-Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m

jvm参数说明:

  • -server:一定要作为第一个参数,在多个CPU时性能佳

  • -Xms:Java Heap初始大小。默认是物理内存的1/64。

  • -Xmx:Java Heap最大值。建议均设为物理内存的一半。不可超过物理内存。

  • -XX:PermSize:设定内存的永久保存区初始大小,缺省值为64M。(我用visualvm.exe查看的)

  • -XX:MaxPermSize:设定内存的永久保存区最大大小,缺省值为64M。(我用visualvm.exe查看的)

  • -XX:SurvivorRatio=2:生还者池的大小,默认是2,如果垃圾回收变成了瓶颈,您可以尝试定制生成池设置。

  • -XX:NewSize:新生成的池的初始大小。缺省值为2M。

  • -XX:MaxNewSize:新生成的池的最大大小。缺省值为32M。

如果 JVM 的堆大小大于 1GB,则应该使用值:-XX:newSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16,或者将堆的总大小的 50% 到 60% 分配给新生成的池。调大新对象区,减少Full GC次数。

  • +XX:AggressiveHeap会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。

  • -Xss:每个线程的Stack大小,“-Xss 15120” 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512k.

  • -verbose:gc:现实垃圾收集信息

  • -Xloggc:gc.log:指定垃圾收集日志文件

  • -Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一

  • -XX:+UseParNewGC:缩短minor收集的时间

  • -XX:+UseConcMarkSweepGC:缩短major收集的时间 此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。

  • -XX:userParNewGC:可用来设置并行收集【多CPU】

  • -XX:ParallelGCThreads:可用来增加并行度【多CPU】

  • -XX:UseParallelGC:设置后可以使用并行清除收集器【多CPU】

转自:https://blog.linuxeye.com/428.html

logrotate是个强大的系统软件,它对日志文件有着一套完整的操作模式,譬如:转储、邮件和压缩等,并且默认logrotate加到cron(/etc/cron.daily/logrotate)作为每日任务执行。自动有了logrotate,我想不用再自己写日志切割脚本。

如下对Tomcat日志catalina.out日志切割

1
2
# ls -lh /usr/local/tomcat/logs/catalina.out
-rw-r--r-- 1 www www 14M Aug 28 15:55 /usr/local/tomcat/logs/catalina.out

配置logrotate对catalina.out日志切割

1
2
3
4
5
6
7
8
9
10
# cat /etc/logrotate.d/tomcat
/usr/local/tomcat/logs/catalina.out {
daily
rotate 5
missingok
dateext
compress
notifempty
copytruncate
}

参数详解:

  • daily 指定转储周期为每天
  • rotate 5 指定日志文件删除之前转储的次数,0指没有备份,5指保留5个备份
  • missingok 如果日志不存在则忽略该警告信息
  • dateext 文件后缀是日期格式,也就是切割后文件是:xxx.log-20150828.gz
  • compress 通过gzip压缩转储以后的日志(gzip -d xxx.gz解压)
  • notifempty 如果是空文件的话,不转储
  • copytruncate 用于还在打开中的日志文件,把当前日志备份并截断

立即截断日志:

1
# logrotate --force /etc/logrotate.d/tomcat

效果如下:

1
2
3
# ls -lh /usr/local/tomcat/logs/catalina.out*  
-rw-r--r-- 1 www www 0 Aug 28 16:00 /usr/local/tomcat/logs/catalina.out
-rw-r--r-- 1 www www 1.1M Aug 28 16:00 /usr/local/tomcat/logs/catalina.out-20150828.gz

读书笔记 - Java 多线程编程实战指南


第十四章 Half-sync/Half-async(半同步/半异步)模式

模式介绍

  • Half-sync/Half-async 模式集成了同步编程和异步编程的优势,它通过同步任务和异步任务的共同协作来完成一个计算,即保持了同步编程的简单性,又充分发挥异步编程在提高系统并发性方面的优势。该模式就如一个称职的管理者,知晓不同下属各自的优势和弱点,在指派任务的时候能够根据下属的优势和弱点扬长避短,并使各个下属相互协作,共同完成工作。
阅读全文 »

读书笔记 - Java 多线程编程实战指南


第十三章 Pipeline(流水线)模式

模式介绍

  • Pipeline 模式的核心思想是将一个任务处理分解为若干个处理阶段(Stage),其中每个处理阶段的输出作为下一个处理阶段的输入,并且各个处理阶段都有相应的工作者线程去执行相应的计算。因此,处理一批任务时,各个任务的各个处理阶段是并行(Parallel)的。通过并行计算,Pipeline 模式使应用程序能够充分利用多核 CPU 资源,提高其计算效率。
  • 假设有一批任务(T1、T2、T3、T4),其中每个任务的处理可分解为 3 个处理阶段。虽然,对于这一批任务中的某一个任务而言,其处理仍然是串行的,即完成一个任务的处理要一次执行各个处理阶段,但从整体任务上看,各个处理阶段的执行是并行的。比如,处理阶段 1 的工作者线程执行完任务 T1 相应的计算后,其处理结果会被提交给处理阶段 2 作为输入;当处理阶段 2 的工作者线程正在执行任务 T1 的相应的计算时,处理阶段 1 正在执行任务 T2 相应的计算,此时这两个处理阶段时并行的。
阅读全文 »

读书笔记 - Java 多线程编程实战指南


第十二章 Master-Slave(主仆)模式

模式介绍

  • Master-Slave 模式是一个基于分而治之(Divide and conquer)思想的设计模式。其核心思想是将一个任务(原始任务)分解为若干个语义等同(Semantically-identical)的子任务,并由专门的工作者线程来并行执行这些子任务。原始任务的处理结果是通过整合各个子任务的处理结果而形成的。而这些与分而治之相关的处理细节对于原始任务的提交方来说又是不可见的,因此,Master-Slave 模式既提高计算效率,又实现了信息隐藏。
阅读全文 »

读书笔记 - Java 多线程编程实战指南


第十一章 Serial Thread Confinement(串行线程封闭)模式

模式介绍

  • 如果并发任务的执行涉及某个非线程安全对象,而我们又希望因此而引入锁,那么我们可以考虑使用 Serial Thread Confinement 模式。
  • Serial Thread Confinement 模式的核心思想是通过将多个并发的任务存入队列实现任务的串行化,并为这些串行化的任务创建唯一的一个工作者线程进行处理。因此,这个唯一的工作者线程所访问的非线程安全对象由于只有一个线程访问它,对其的访问自然无需加锁,从而避免了锁的开销及由锁可能引发的问题。
  • 当然,如果我们对并发任务访问的非线程安全对象进行加锁,也能实现任务的串行化从而实现线程安全,另外 Serial Thread Confinement 模式串行化并发任务所使用的队列本身也会涉及锁。因此,Serial Thread Confinement 模式的本质是使用一个开销更小的锁(串行化并发任务时所用队列涉及的锁)去替代另一个可能的开销更大的锁(为保障并发任务所访问的非线程安全对象可能引入的锁)。
阅读全文 »