package ringBuffer;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
public class PerformanceWriteTest {
/**
* @param args
*/
public static void main(String[] args) {
String outputFile = "F:\\test\\ioTest.txt";
Long length = 0L ;
Long totalTime = 0L;
for (int j = 0; j < 5; j++) {
StringBuffer sb = new StringBuffer();
for (Integer i = 0; i < 1000000; i++) {
sb.append(j+i.toString() + "V");
}
sb.append("S");
length = (long) sb.toString().length() ;
long start = System.currentTimeMillis() ;
appendFileTest(outputFile,sb.toString());
totalTime = totalTime + (System.currentTimeMillis() - start) ;
}
System.out.println(" Total Data is : " + length*5/1000 + " Kbytes! ") ;
System.out.println(" Total Time is : " + totalTime) ;
System.out.println(" Averge Speed is :" + length*5/(totalTime*1000) + " Kbytes");
}
private static void appendFileTest(String outputFile, String msgs) {
// append1(outputFile, msgs) ; //FileOutputStream
// append2(outputFile, msgs) ; //FileWriter
append3(outputFile, msgs) ; //RandomAccessFile
// append4(outputFile, msgs) ; //RandomAccessFile
}
private static void append1(String outputFile, String msgs) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFile, true)));
out.append(msgs) ;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void append2(String outputFile, String msgs) {
try {
FileWriter writer = new FileWriter(outputFile, true);
writer.write(msgs);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void append3(String outputFile, String msgs) {
try {
RandomAccessFile randomFile = new RandomAccessFile(outputFile, "rw");
long fileLength = randomFile.length();
randomFile.seek(fileLength);
randomFile.writeBytes(msgs);
randomFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void append4(String outputFile, String msgs) {
try {
mbb.position(pos) ;
mbb.put(msgs.getBytes());
pos = pos + msgs.getBytes().length ;
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
static RandomAccessFile raf ;
static MappedByteBuffer mbb ;
static Integer pos = 0 ;
}
use -XX::+PrintGC option, the result is :
[GC 32704K->2928K(124992K), 0.0024320 secs]
[GC 35632K->5200K(124992K), 0.0020096 secs]
[GC 29268K->5200K(124992K), 0.0014802 secs]
[GC 37904K->9792K(157696K), 0.0035590 secs]
[GC 60504K->9840K(157696K), 0.0008594 secs]
[GC 75248K->28224K(224640K), 0.0079131 secs]
[GC 159040K->30572K(224768K), 0.0014706 secs]
[GC 159705K->37516K(355008K), 0.0029869 secs]
[GC 299148K->46668K(355008K), 0.0031385 secs]
[GC 308300K->48980K(511296K), 0.0010842 secs]
[GC 467604K->55860K(511616K), 0.0036752 secs]
可以看出有11次GC,但是,当我使用jstat -gcutil pid时 结果是:
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 12.01 0.00 11.93 0 0.000 0 0.000 0.000
0.00 0.00 12.01 0.00 11.93 0 0.000 0 0.000 0.000
0.00 54.32 5.86 0.01 11.94 1 0.002 0 0.000 0.002
0.00 54.32 5.86 0.01 11.94 1 0.002 0 0.000 0.002
96.58 0.00 0.00 0.01 11.94 2 0.004 0 0.000 0.004
96.58 0.00 21.54 0.01 11.94 2 0.004 0 0.000 0.004
0.00 96.58 0.00 0.01 11.94 3 0.006 0 0.000 0.006
0.00 96.58 82.32 0.01 11.94 3 0.006 0 0.000 0.006
10.57 0.00 0.00 10.61 11.94 4 0.009 0 0.000 0.009
10.57 0.00 0.00 10.61 11.94 4 0.009 0 0.000 0.009
10.57 0.00 41.35 10.61 11.94 4 0.009 0 0.000 0.009
10.57 0.00 41.35 10.61 11.94 4 0.009 0 0.000 0.009
0.00 11.46 40.92 10.61 11.94 5 0.010 0 0.000 0.010
0.00 11.46 40.92 10.61 11.94 5 0.010 0 0.000 0.010
0.00 11.46 40.92 10.61 11.94 5 0.010 0 0.000 0.010
0.00 11.46 93.70 10.61 11.94 6 0.010 0 0.000 0.010
8.22 0.00 0.00 31.82 11.94 6 0.018 0 0.000 0.018
8.22 0.00 18.62 31.82 11.94 6 0.018 0 0.000 0.018
8.22 0.00 18.62 31.82 11.94 6 0.018 0 0.000 0.018
8.22 0.00 18.62 31.82 11.94 6 0.018 0 0.000 0.018
8.22 0.00 70.07 31.82 12.06 6 0.018 0 0.000 0.018
8.22 0.00 70.07 31.82 12.06 6 0.018 0 0.000 0.018
8.22 0.00 89.85 31.82 12.07 6 0.018 0 0.000 0.018
8.22 0.00 89.85 31.82 12.07 7 0.018 0 0.000 0.018
0.00 34.09 0.00 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 19.26 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 19.26 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 53.07 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 53.07 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 53.07 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 79.83 32.41 12.07 7 0.020 0 0.000 0.020
0.00 34.09 79.83 32.41 12.07 7 0.020 0 0.000 0.020
1.98 0.00 10.34 43.02 12.07 8 0.023 0 0.000 0.023
1.98 0.00 10.34 43.02 12.07 8 0.023 0 0.000 0.023
1.98 0.00 10.34 43.02 12.07 8 0.023 0 0.000 0.023
1.98 0.00 23.53 43.02 12.07 8 0.023 0 0.000 0.023
1.98 0.00 23.53 43.02 12.07 8 0.023 0 0.000 0.023
1.98 0.00 36.71 43.02 12.07 8 0.023 0 0.000 0.023
仅为GC的8倍。
我的问题是:
jstat -gccapacity pid
,我可以获得NGCMX :695616.0 OGCMX :1391296.0
答案 0 :(得分:1)
垃圾收集器完成收集所花费的总时间取决于几个因素,但仅举几例
在YGCT的情况下,我可以猜测,随着越来越多的物体可以到达(它们被标记为实时),标记它们并将它们移动到幸存者空间增加所需的时间。但要确定这一点,我们需要获得有关GC的更多详细信息。我建议您添加以下标志以获取有关GC的更多信息。
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC
-XX:+PrintTenuringDistribution -Xloggc:/path-to-logs-dir/gc.log
使用这些标记,您将了解更多详细信息,并希望更好地了解GC停顿时间较长的原因。
使用jstat
,了解每个GC中收集的内存并非易事。我已经执行了你的代码(将循环计数器增加到2Million)并使用此命令-gc
每秒收集jstat -gc 5700 1000
个统计数据,结果如下(我删除了几列以使其简洁)< / p>
S0C S1C S0U S1U EC EU OC OU YGC YGCT FGC FGCT GCT
5120.0 5120.0 0.0 0.0 33280.0 2662.6 87552.0 0.0 0 0.000 0 0.000 0.000
5120.0 5120.0 0.0 0.0 33280.0 2662.6 87552.0 0.0 0 0.000 0 0.000 0.000
5120.0 5120.0 0.0 0.0 33280.0 2662.6 87552.0 0.0 0 0.000 0 0.000 0.000
5120.0 5120.0 0.0 0.0 33280.0 2662.6 87552.0 0.0 0 0.000 0 0.000 0.000
3584.0 5120.0 64.0 0.0 265216.0 0.0 102912.0 37158.5 8 0.035 1 0.007 0.043
512.0 4608.0 0.0 0.0 407552.0 48864.8 128000.0 37159.2 10 0.054 3 0.019 0.072
4608.0 4608.0 0.0 0.0 419328.0 263176.3 126464.0 18944.2 11 0.063 4 0.023 0.087
4608.0 4608.0 0.0 0.0 594944.0 475327.6 209920.0 70145.4 12 0.092 5 0.034 0.127
4096.0 4608.0 0.0 32.0 594944.0 384988.3 209920.0 107009.4 13 0.099 5 0.034 0.134
正如你在第5行所看到的那样,在那一秒钟内,发生了8个年轻的基因发生,并且没有办法只用这些统计数据知道每个GC的年轻大小。当然,您可以将间隔减少到100毫秒,如果您很幸运,您可能会找到内存,但它并不总是可靠,但使用上面提到的GC标记,信息始终是精确的。
以下是带有程序标志的GC输出
{Heap before GC invocations=1 (full 0):
PSYoungGen total 38400K, used 33280K [0x00000000d5980000, 0x00000000d8400000, 0x0000000100000000)
eden space 33280K, 100% used [0x00000000d5980000,0x00000000d7a00000,0x00000000d7a00000)
from space 5120K, 0% used [0x00000000d7f00000,0x00000000d7f00000,0x00000000d8400000)
to space 5120K, 0% used [0x00000000d7a00000,0x00000000d7a00000,0x00000000d7f00000)
ParOldGen total 87552K, used 0K [0x0000000080c00000, 0x0000000086180000, 0x00000000d5980000)
object space 87552K, 0% used [0x0000000080c00000,0x0000000080c00000,0x0000000086180000)
Metaspace used 2454K, capacity 4494K, committed 4864K, reserved 1056768K
class space used 265K, capacity 386K, committed 512K, reserved 1048576K
0.207: [GC (Allocation Failure)
Desired survivor size 5242880 bytes, new threshold 7 (max 15)
[PSYoungGen: 33280K->2736K(38400K)] 33280K->2744K(125952K), 0.0178152 secs] [Times: user=0.00 sys=0.00, real=0.02 secs]
Heap after GC invocations=1 (full 0):
PSYoungGen total 38400K, used 2736K [0x00000000d5980000, 0x00000000d8400000, 0x0000000100000000)
eden space 33280K, 0% used [0x00000000d5980000,0x00000000d5980000,0x00000000d7a00000)
from space 5120K, 53% used [0x00000000d7a00000,0x00000000d7cac020,0x00000000d7f00000)
to space 5120K, 0% used [0x00000000d7f00000,0x00000000d7f00000,0x00000000d8400000)
ParOldGen total 87552K, used 8K [0x0000000080c00000, 0x0000000086180000, 0x00000000d5980000)
object space 87552K, 0% used [0x0000000080c00000,0x0000000080c02000,0x0000000086180000)
Metaspace used 2454K, capacity 4494K, committed 4864K, reserved 1056768K
class space used 265K, capacity 386K, committed 512K, reserved 1048576K
}
从上面可以清楚地看出,在GC
之前,它只有一个年轻的GC作为完整的GC是0 GC之后的 Young Gen usage is 33MB, Old Gen is 0 MB
Young Gen is 2.7MB and Old Gen is 8k
很明显,在第一次GC之后,~30.5MB
被释放。所以GC日志是你最好的选择,并注意他们理解分配率和GC模式。
希望这会有所帮助:)