Como especificar o tamanho máximo de heap JVM “-Xmx” para executar um aplicativo com ação “executar” no SBT?

97

Meu aplicativo faz um grande processamento de matrizes de dados e precisa de mais memória do que a JVM fornece por padrão. Eu sei que em Java é especificado pela opção "-Xmx". Como configuro o SBT para usar o valor "-Xmx" específico para executar um aplicativo com a ação "executar"?

Ivan
fonte

Respostas:

17

Experimente isto:

class ForkRun(info: ProjectInfo) extends DefaultProject(info) {
    override def fork = Some(new ForkScalaRun {
        override def runJVMOptions = super.runJVMOptions ++ Seq("-Xmx512m")
        override def scalaJars = Seq(buildLibraryJar.asFile, buildCompilerJar.asFile)
    })
}
Arne
fonte
53
Este está desatualizado, agora você pode usarjavaOptions += "-Xmx1G"
iwein
1
@iwein o conteúdo da minha postagem parece ser muito importante para você.
Arne
2
Note-se que javaOptionsapenas ter efeito para JVMs bifurcadas (ver scala-sbt.org/0.13/docs/Forking.html )
Yar
1
Adicionar fork in run := ture habilitajavaOptions
coanor de
@coanor esta resposta é para uma versão antiga do sbt. Há uma resposta com classificações muito mais altas logo abaixo desta. Essa resposta foi a resposta correta no momento em que a pergunta foi feita.
Arne de
113

Para processos bifurcados, você deve olhar para Build.scala

Para modificar as opções java para processos bifurcados, você precisa especificá-los no Build.scala (ou qualquer outro nome que você tenha nomeado para sua construção), como este:

val buildSettings = Defaults.defaultSettings ++ Seq(
   //…
   javaOptions += "-Xmx1G",
   //…
)

Isso lhe dará as opções adequadas sem modificar JAVA_OPTS globalmente e colocará JAVA_OPTS personalizado em um script inicial gerado por sbt

Para processos não bifurcados , é mais conveniente definir a configuração via sbtoptsou sbtconfigdependendo da versão do sbt.

Já que o sbt 0.13.6 .sbtconfigestá obsoleto . Modifique /usr/local/etc/sbtoptsao longo destas linhas:

-J-Xms512M
-J-Xmx3536M
-J-Xss1M
-J-XX:+CMSClassUnloadingEnabled
-J-XX:+UseConcMarkSweepGC
-J-XX:MaxPermSize=724M
-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

Você também pode criar um .sbtoptsarquivo na raiz do seu projeto SBT usando a mesma sintaxe do /usr/local/etc/sbtoptsarquivo. Isso torna o projeto independente.

Antes do sbt 0.13.6, você podia definir as opções em .sbtconfig para processos não bifurcados :

  1. Verifique onde está sbt:

    $ which sbt
    /usr/local/bin/sbt
    
  2. Veja o conteúdo:

    $ cat /usr/local/bin/sbt
    #!/bin/sh
    test -f ~/.sbtconfig && . ~/.sbtconfig
    exec java ${SBT_OPTS} -jar /usr/local/Cellar/sbt/0.12.1/libexec/sbt-launch.jar "$@"
    
  3. Defina as opções corretas de jvm para evitar OOM (regular e PermGen):

    $ cat ~/.sbtconfig
    SBT_OPTS="-Xms512M -Xmx3536M -Xss1M 
     -XX:+CMSClassUnloadingEnabled 
     -XX:+UseConcMarkSweepGC -XX:MaxPermSize=724M"
    

Se você deseja definir SBT_OPTS apenas para a execução atual do sbt, pode usar env SBT_OPTS=".." sbtconforme sugerido por Googol Shan. Ou você pode usar a opção adicional no SBT 12: sbt -mem 2048. Isso fica difícil para listas de opções mais longas, mas pode ajudar se você tiver projetos diferentes com necessidades diferentes.

Observe que CMSClassUnloadingEnabled em conjunto com UseConcMarkSweepGC ajuda a manter o espaço PermGen limpo, mas dependendo de quais estruturas você usa, pode haver um vazamento real no PermGen, que eventualmente força uma reinicialização.

iwein
fonte
@iwein - O javaOptions não alterou o heapspace padrão para sbt. Eu verifiquei no jconsole e ele mostra apenas -Xmx512M. Mesmo se eu adicionar SBT_OPTS em ~ / .sbtconfig, ainda recebo isso no jconsole: -Xmx512M -Xms256M -Xmx1G -XX: MaxPermSize = 256M -XX: + UseConcMarkSweepGC. Você vê o Xmx512 na frente? De alguma forma, não escolhe javaOptions de Build.scala. Quaisquer dicas?
Anand
@Anand talvez as coisas estejam funcionando de maneira um pouco diferente no 0.13? Atualizarei a resposta se encontrar algo (pode demorar um pouco). Avise-me se você descobrir isso nesse meio tempo.
iwein
@iwein Acabei de usar o seguinte no meu Build.scala e funcionou. fork in run: = true, javaOptions in run ++ = Seq ("- Xms256m", "-Xmx2048m", "-XX: + UseConcMarkSweepGC"). Veja esta postagem para a resposta stackoverflow.com/questions/27372468/… . Obrigado!
Anand
2
Para sua informação, você também pode criar um .sbtoptsarquivo na raiz do seu projeto SBT usando a mesma sintaxe do /usr/local/etc/sbtoptsarquivo. Isso torna seu projeto independente, o que pode ser muito útil em situações de CI.
Idade Mooij
No Windows usando 0.13.9 (pode ser 0.13.6), o arquivo é C: \ Arquivos de Programas (x86) \ sbt \ conf \ sbtconfig.txt. Por padrão, o arquivo tinha "-Xmx512M" sem o -J mostrado nesta resposta. Posso confirmar que este arquivo está sendo lido pelo fato de que o assembly sbt emite um aviso sobre -XX: MaxPermSize e quando eu altero esse valor o aviso mostra o valor que eu inseri e não o valor "256m" mostrado originalmente.
Night Owl
68

Na versão 12 em diante do sbt, há uma opção para isso:

$sbt -mem 2048 
Prashant Sharma
fonte
5
na vitória 8.1, este comando não funcionou para mim:Not a valid command: mem (similar: set)
Kevin Meredith
43

Se você executar o sbt no shell do Linux, poderá usar:

env JAVA_OPTS="-Xmx512m" sbt run

Este é o meu comando normalmente usado para executar meu projeto sbt.

Googol Shan
fonte
1
Muito obrigado. Um comando legal de saber. Nunca soube desse "env" e muitas vezes deixei passar essa ferramenta.
Ivan
4
Hmm, isso não funcionou para mim! Eu precisava da override def forksolução acima. (sbt 0.7.7)
Scott Morrison
2
é possível que seu arquivo sbt especifique seu próprio JAVA_OPTS, caso em que eles serão sobrescritos. Você pode então modificar diretamente seu arquivo sbt, seja para remover o sinalizador -Xmx ou para alterná-lo para o tamanho de heap máximo desejado.
nnythm
23

.sbtconfigestá obsoleto a partir do SBT 0.13.6. Em vez disso, configurei essas opções /usr/local/etc/sbtoptsda seguinte maneira:

-J-Xms512M
-J-Xmx3536M
-J-Xss1M
-J-XX:+CMSClassUnloadingEnabled
-J-XX:+UseConcMarkSweepGC
-J-XX:MaxPermSize=724M
-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
omnomnom
fonte
1
-J-Xss1Mé um pouco baixo para classes grandes, 4M parece ser mais seguro.
Marius Soutier
7

Existe uma maneira que eu conheço. Defina a variável de ambiente JAVA_OPTS.

JAVA_OPTS='-Xmx512m'

Não encontrei uma maneira de fazer isso como um parâmetro de comando.

Synesso
fonte
7

Use JAVA_OPTS para configurar com a variável de ambiente.

Use as opções -JX para sbt para opções individuais, por exemplo, -J-Xmx2048 -J-XX: MaxPermSize = 512

As versões mais recentes do sbt têm uma opção "-mem".

Brett
fonte
5

O javaOptions += "-XX:MaxPermSize=1024"em nosso build.sbt, conforme referenciado por @iwein acima, funcionou para nós quando vimos um java.lang.OutOfMemoryError lançado durante a execução de testes Specs2 por meio de sbt.

Pete Neisen
fonte
1
@UwePlonus ele responde à pergunta.
VasiliNovikov
3

A variável de ambiente é _JAVA_OPTIONS, que precisa ser definida. Depois de definir _JAVA_OPTIONS, e quando você sbt, sbt mostrará a mensagem usando JAVA_OPTIONS e os valores.

Alternativamente, você pode definir javaOption no arquivo sbt ou .scala, por exemplo

javaOptions += "-Xmx1G"

Do shell sbt, você pode executar show javaOptions para ver os valores definidos.

Sajive Kumar
fonte
1
    javaOptions in Test += "-Xmx1G"

Isso define as opções de JVM para testes. Funciona também com jvm forking ( fork in Test := true).

VasiliNovikov
fonte
1
onde isso está definido no build.sbt?
javadba de
Em qualquer lugar, se você tiver um projeto de 1 módulo. A ordem das definições geralmente não importa no SBT. Se você tiver vários módulos, especifique isso em alguns deles ou, se quiser, globalmente via javaOptions in ThisBuild += "-Xmx1G"oujavaOptions in (ThisBuild, Test) += "-Xmx1G"
VasiliNovikov