Java在内存分配期间使用多个线程

时间:2014-09-10 18:38:26

标签: java multithreading memory-management

我正在编写一个分配大型多维数组进行处理的java程序。在分配期间,java最终使用它可用的所有CPU(在我的例子中,8个CPU)。这是预期的行为吗?我正在使用java版本1.7.0_65运行Ubuntu 14.04。如果您需要更多信息,请告诉我。如果这是预期的行为,有没有办法限制它,以便它只使用一个CPU?

public class test {
    public static void main(String[] args){
        System.out.println("Test");

        int a = 1000;
        int b = 100;
        int c = 100;
        int d = 1;
        int e = 10;
        float[][][][][] test = new float[a][b][c][d][e];


        System.out.println("Done");
    }
}

编辑:通过将初始堆大小设置得足够大,程序永远不会使用多个CPU。在将来,我将使用足够大的初始JVM大小和taskset命令来限制cpu affiinty。

3 个答案:

答案 0 :(得分:3)

分配始终在当前线程中执行,但如果堆上的空间不足,则分配请求可以触发垃圾收集,这取决于JVM及其垃圾收集器调整参数,可以使用多个线程。

在Oracle JVM上,您可以通过向Java进程提供-verbose:gc选项来验证确实是这种情况。在我的计算机上,程序然后生成以下输出:

Test
[GC (Allocation Failure)  512K->456K(261632K), 0.0007027 secs]
[GC (Allocation Failure)  968K->920K(261632K), 0.0014950 secs]
[GC (Allocation Failure)  1432K->1452K(261632K), 0.0011264 secs]
[GC (Allocation Failure)  1964K->1972K(262144K), 0.0009485 secs]
[GC (Allocation Failure)  2996K->3020K(262144K), 0.0011456 secs]
[GC (Allocation Failure)  4044K->4172K(264704K), 0.0014029 secs]
[GC (Allocation Failure)  6220K->6124K(264704K), 0.0032563 secs]
[GC (Allocation Failure)  8172K->8212K(267776K), 0.0032141 secs]
[GC (Allocation Failure)  11796K->11836K(268288K), 0.0048205 secs]
[GC (Allocation Failure)  15420K->15524K(271872K), 0.0048205 secs]
[GC (Allocation Failure)  20644K->20772K(272896K), 0.0063642 secs]
[GC (Allocation Failure)  25892K->25900K(275968K), 0.0066470 secs]
[GC (Allocation Failure)  33580K->33636K(276480K), 0.0069722 secs]
[GC (Allocation Failure)  41316K->41396K(281088K), 0.0105088 secs]
[GC (Allocation Failure)  52660K->52564K(282112K), 0.0095962 secs]
[GC (Allocation Failure)  63828K->64060K(293376K), 0.0127885 secs]
[GC (Allocation Failure)  81468K->81380K(294400K), 0.0138240 secs]
[GC (Allocation Failure)  98788K->99004K(307712K), 0.0192218 secs]
[GC (Allocation Failure)  122044K->122196K(309248K), 0.0170214 secs]
[GC (Allocation Failure)  145236K->145284K(318976K), 0.0242662 secs]
[GC (Allocation Failure)  174468K->174620K(322048K), 0.0219776 secs]
[GC (Allocation Failure)  203804K->203860K(334336K), 0.0287066 secs]
[GC (Allocation Failure)  241236K->241356K(337920K), 0.0252992 secs]
[GC (Allocation Failure)  278732K->278916K(354816K), 0.0359923 secs]
[Full GC (Ergonomics)  278916K->277284K(400384K), 1.5867443 secs]
[GC (Allocation Failure)  325412K->325695K(404992K), 0.0360435 secs]
[Full GC (Ergonomics)  325695K->325411K(449024K), 0.7776627 secs]
[GC (Allocation Failure)  373539K->373719K(449024K), 0.0383219 secs]
[Full GC (Ergonomics)  373719K->373537K(493056K), 0.8760845 secs]
[GC (Allocation Failure)  414497K->414792K(506368K), 0.0410957 secs]
[Full GC (Ergonomics)  414792K->414495K(553472K), 0.9881370 secs]
[GC (Allocation Failure)  455455K->455705K(549376K), 0.0421990 secs]
[GC (Allocation Failure)  491545K->491545K(557568K), 0.0329242 secs]
[Full GC (Ergonomics)  491545K->491290K(604160K), 1.1687245 secs]
[GC (Allocation Failure)  527130K->527471K(621568K), 0.0546765 secs]
[Full GC (Ergonomics)  527471K->527127K(676864K), 1.2818099 secs]
[GC (Allocation Failure)  565527K->565750K(679424K), 0.0519078 secs]
[GC (Allocation Failure)  604150K->604174K(669184K), 0.0404352 secs]
[GC (Allocation Failure)  623630K->623910K(690176K), 0.0469939 secs]
[Full GC (Ergonomics)  623910K->623379K(753152K), 1.6304653 secs]
[GC (Allocation Failure)  642835K->643153K(751616K), 0.0642752 secs]
[GC (Allocation Failure)  655441K->655473K(760832K), 0.0408013 secs]
[GC (Allocation Failure)  667761K->667761K(760320K), 0.0448666 secs]
[GC (Allocation Failure)  668273K->668273K(773632K), 0.0452070 secs]
[GC (Allocation Failure)  668785K->668785K(784896K), 0.0464397 secs]
[GC (Allocation Failure)  669297K->669297K(785408K), 0.0455053 secs]
[GC (Allocation Failure)  669809K->669841K(799232K), 0.0461530 secs]
[GC (Allocation Failure)  670353K->670401K(696320K), 0.0496845 secs]
[Full GC (Ergonomics)  670401K->669956K(762880K), 1.6411686 secs]
[GC (Allocation Failure)  670468K->670818K(855552K), 0.0602765 secs]
[GC (Allocation Failure)  671842K->671778K(721408K), 0.0332749 secs]
[GC (Allocation Failure)  672802K->672770K(846848K), 0.0333530 secs]
[GC (Allocation Failure)  674306K->674426K(711680K), 0.0328486 secs]
[Full GC (Ergonomics)  674426K->674045K(778240K), 0.6690573 secs]
[GC (Allocation Failure)  675581K->675704K(913408K), 0.0583846 secs]
[GC (Allocation Failure)  676216K->676184K(914944K), 0.0275571 secs]
[GC (Allocation Failure)  676696K->676760K(912896K), 0.0276851 secs]
[GC (Allocation Failure)  677784K->677768K(744448K), 0.0277325 secs]
[GC (Allocation Failure)  678792K->678824K(903168K), 0.0281344 secs]
[GC (Allocation Failure)  680360K->680360K(747520K), 0.0280448 secs]
[GC (Allocation Failure)  681896K->681896K(889856K), 0.0294963 secs]
[GC (Allocation Failure)  683944K->683912K(751616K), 0.0298778 secs]
[GC (Allocation Failure)  685960K->685992K(874496K), 0.0305114 secs]
[GC (Allocation Failure)  688552K->688616K(756736K), 0.0308301 secs]
[GC (Allocation Failure)  691176K->691144K(860160K), 0.0315098 secs]
[GC (Allocation Failure)  694728K->694696K(763904K), 0.0317261 secs]
[GC (Allocation Failure)  698280K->698312K(844800K), 0.0324186 secs]
[GC (Allocation Failure)  702920K->702952K(773120K), 0.0329357 secs]
[GC (Allocation Failure)  707560K->707616K(834048K), 0.0336230 secs]
[GC (Allocation Failure)  713248K->713264K(782336K), 0.0331354 secs]
[GC (Allocation Failure)  718896K->718928K(835072K), 0.0336960 secs]
[GC (Allocation Failure)  726096K->726200K(836608K), 0.0341606 secs]
[GC (Allocation Failure)  733368K->733344K(836608K), 0.0368486 secs]
[GC (Allocation Failure)  740000K->740064K(838656K), 0.0377613 secs]
[GC (Allocation Failure)  746720K->746768K(839680K), 0.0393101 secs]
[GC (Allocation Failure)  750864K->750864K(843776K), 0.0390566 secs]
[GC (Allocation Failure)  754960K->755064K(845312K), 0.0392218 secs]
[GC (Allocation Failure)  756600K->756640K(848896K), 0.0383347 secs]
[GC (Allocation Failure)  758176K->758208K(850432K), 0.0379328 secs]
[GC (Allocation Failure)  759232K->759200K(804864K), 0.0378035 secs]
[GC (Allocation Failure)  760224K->760304K(846848K), 0.0400614 secs]
[GC (Allocation Failure)  761840K->761848K(795136K), 0.0382733 secs]
[GC (Allocation Failure)  763384K->763432K(835584K), 0.0364710 secs]
[GC (Allocation Failure)  765480K->765568K(787968K), 0.0364749 secs]
[GC (Allocation Failure)  767616K->767632K(834048K), 0.0357376 secs]
[Full GC (Ergonomics)  767632K->766656K(881152K), 1.1594624 secs]
[GC (Allocation Failure)  769216K->769444K(882688K), 0.0689485 secs]
[GC (Allocation Failure)  772004K->772044K(884224K), 0.0334374 secs]
[GC (Allocation Failure)  775116K->775188K(884224K), 0.0350246 secs]
[GC (Allocation Failure)  778260K->778300K(881664K), 0.0336294 secs]
[GC (Allocation Failure)  782396K->782396K(810496K), 0.0337357 secs]
[GC (Allocation Failure)  786492K->786524K(877056K), 0.0349286 secs]
[GC (Allocation Failure)  791644K->791684K(816640K), 0.0353728 secs]
[GC (Allocation Failure)  796804K->796876K(869888K), 0.0359552 secs]
[GC (Allocation Failure)  803020K->803068K(820736K), 0.0366515 secs]
[Full GC (Ergonomics)  803068K->802478K(869888K), 1.8098995 secs]
[GC (Allocation Failure)  808622K->808797K(913920K), 0.0726835 secs]
[GC (Allocation Failure)  815965K->815997K(872448K), 0.0363674 secs]
Done

正如您所看到的,JVM花费大部分时间来反复尝试垃圾回收。这是因为JVM会在增加堆大小之前首先尝试收集垃圾。您可以通过指示JVM以适当大的堆开始来避免这种情况。再次假设Oracle JVM,您可以通过在命令行上提供-Xms1g来实现此目的。然后,输出要短得多:

Test
[GC (Allocation Failure)  511K->496K(1048064K), 0.0007194 secs]
[GC (Allocation Failure)  1008K->904K(1048064K), 0.0014771 secs]
[GC (Allocation Failure)  1416K->1456K(1048064K), 0.0011328 secs]
[GC (Allocation Failure)  1968K->1996K(1048576K), 0.0011072 secs]
[GC (Allocation Failure)  3020K->3068K(1048576K), 0.0011904 secs]
[GC (Allocation Failure)  4092K->4252K(1051136K), 0.0012557 secs]
[GC (Allocation Failure)  6300K->6148K(1051136K), 0.0033741 secs]
[GC (Allocation Failure)  8196K->8228K(1054208K), 0.0032742 secs]
[GC (Allocation Failure)  11812K->11852K(1054720K), 0.0049498 secs]
[GC (Allocation Failure)  15436K->15604K(1058304K), 0.0042598 secs]
[GC (Allocation Failure)  20724K->20772K(1059328K), 0.0058598 secs]
[GC (Allocation Failure)  25892K->25972K(1062400K), 0.0061824 secs]
[GC (Allocation Failure)  33652K->33700K(1062912K), 0.0076966 secs]
[GC (Allocation Failure)  41380K->41476K(1067520K), 0.0083110 secs]
[GC (Allocation Failure)  52740K->52620K(1068544K), 0.0101210 secs]
[GC (Allocation Failure)  63884K->64060K(1079808K), 0.0126912 secs]
[GC (Allocation Failure)  81468K->81436K(1080832K), 0.0131405 secs]
[GC (Allocation Failure)  98844K->99052K(1093120K), 0.0189248 secs]
[GC (Allocation Failure)  121580K->121684K(1095168K), 0.0154816 secs]
[GC (Allocation Failure)  144212K->144308K(1105408K), 0.0233011 secs]
[GC (Allocation Failure)  173492K->173556K(1107968K), 0.0199322 secs]
[GC (Allocation Failure)  202740K->202860K(1120768K), 0.0276851 secs]
[GC (Allocation Failure)  240236K->240396K(1124352K), 0.0240986 secs]
[GC (Allocation Failure)  277772K->277908K(1140736K), 0.0352077 secs]
[GC (Allocation Failure)  326036K->326180K(1145344K), 0.0325568 secs]
[GC (Allocation Failure)  374308K->374484K(1161728K), 0.0419046 secs]
[GC (Allocation Failure)  431316K->431548K(1167872K), 0.0383821 secs]
[GC (Allocation Failure)  488380K->488580K(1187328K), 0.0488973 secs]
[GC (Allocation Failure)  556676K->556860K(1193472K), 0.0427763 secs]
[GC (Allocation Failure)  624956K->625220K(1216000K), 0.0556787 secs]
[GC (Allocation Failure)  706628K->706852K(1223168K), 0.0524774 secs]
[GC (Allocation Failure)  788260K->788492K(1249792K), 0.0675712 secs]
Done

特别是,没有任何主要的垃圾收集,程序只占CPU时间的一小部分。

当然,如果在程序过程中反复创建如此大的数组,则会发生垃圾收集,并且临时使用其他核心可能仍然是一个问题。在这种情况下,我建议通过其配置选项调整垃圾收集器,以某种方式诱使JVM相信可用的内核更少,或者限制操作系统级别的活动JVM线程数。

答案 1 :(得分:2)

这里没有显式使用任何多线程代码,所以如果你看到多CPU使用可能其他线程是JVM内部,你无法控制它们。

答案 2 :(得分:0)

你遇到的问题是Java不能做原生的多维数组。相反,你有一个数组数组数组的数组。如果你得到a = 1000和e = 10那就会快得多。