5

Recently, I've written some Android app in scala, working with Eclipse. Everything was okay until my program had only several classes / activities. When I added more code, JVM started to crash, eclipse often freezed and adb constantly lost connection. Task manager showed that Java process was taking from 800 up to 1300 MB memory!

My computer's hardware parameters are quite nice like i7 3rd gen, 8GB DDR3 and SSD 256. So it's not the reason.

Also my software is up to date and consits of the newest version of Eclipse, Android SDK, Scala and Java development kit, all plugins for eclipse. -vmargs are configured for scala development but it didn't help at all. So I eliminated it to as a cause of problem.

When I rewrite my code to Java everythig goes excellent and I can go on with my project.

Has anyone find already some solution for working with scala in Android project? I read a couple of similar topics here and on google groups but there was no answer on this question.

EDIT:

I profiled my code with visual vm, but heap space usage was normal. Here's some snippet of my code.

imports ...

class MainActivity extends FragmentActivity {
  private lazy val timePicker = findViewById(R.id.timePicker).asInstanceOf[TimePicker]
  private lazy val spinner_sourceBank = findViewById(R.id.spinnerSource).asInstanceOf[Spinner]
  private lazy val spinner_targetBank = findViewById(R.id.spinnerDestination).asInstanceOf[Spinner]
  private lazy val myApplication = getApplication.asInstanceOf[MyApplication]
  private var ignoreTimeChange = false

  override protected def onCreate(savedInstanceState: Bundle) = {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    timePicker.setIs24HourView(true)
    initializeSpinner(spinner_sourceBank)
    initializeSpinner(spinner_targetBank)
  }

  private def initializeSpinner(spinner: Spinner) = {
    val adapter = ArrayAdapter.createFromResource(this, R.array.banks, R.layout.spinner_item)
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
    spinner.setAdapter(adapter)
  }

  def reset(w: View) = {
    timePicker.setCurrentHour(13)
    timePicker.setCurrentMinute(00)
    spinner_sourceBank.setSelection(0)
    spinner_targetBank.setSelection(0)
  }

  def submit(w: View) = {
    if (spinner_sourceBank.getSelectedItemPosition == 0 || spinner_targetBank.getSelectedItemPosition == 0) {
      new AlertDialog.Builder(this).setPositiveButton("OK", new OnClickListener {
        override def onClick(dialog: DialogInterface, which: Int) { dialog dismiss }
      }).setMessage(getString(R.string.alert_title)).setTitle("Alert Dialog").setIcon(android.R.drawable.ic_dialog_alert).create.show
    } else manageFragments(sourceBank, targetBank)
  }

  def manageFragments(sourceBank: String, targetBank: String) = {
    val fragmentTransaction = getSupportFragmentManager.beginTransaction

    if (targetBank == sourceBank) myApplication.setCurrentFragment(MyApplication.NOW)
    else myApplication.setCurrentFragment(MyApplication.FIRST_SESSION)

    fragmentTransaction.replace(R.id.fragment_container, myApplication.getCurrentFragment)
    fragmentTransaction.commit
  }

  override def onCreateOptionsMenu(menu: Menu): Boolean = { getMenuInflater.inflate(R.menu.activity_main, menu); true }
}

I could test my application on mobile device and it ran pretty well. I also could write my code, but eclipse behaved like ran on old computer - switching tabs took a lot of time and so building and deploying.

Kamil Lelonek
  • 14,592
  • 14
  • 66
  • 90
  • Are you sure your scala and java code are identical (can you provide minimized example to reproduce, btw)? Maybe you've introduced infinite loop somewhere or something like that? – om-nom-nom Dec 26 '12 at 10:23
  • Oh, I'm sure that there are any silly mistake like infinity loops. Code is excactly the same. This problem appears not only in my project, but many programmers have also trouble like this. – Kamil Lelonek Dec 26 '12 at 10:27
  • 1
    It still hard to say something useful without code or heapdump. Have you profiled your code (as far as I know, this can be easily done in both visualvm and yourkit)? Have you looked what code parts produces so much objects? Can you show us at least those snippets? – om-nom-nom Dec 26 '12 at 10:33
  • Which version of Scala, and Eclipse plugin are you using ? Depending on versions, plugin can be very slow. Anyway looking at your code what is the benefit of using Scala ? it seems to me your code looks very similar to java or maybe the chosen class does not reflect the sources ? – UBIK LOAD PACK Jan 03 '13 at 19:33
  • Hi. I'm using AndroidProguardScala. I changed eclipse.ini: -vmargs -Xms40m -Xmx1024m, it's working is well. But there is one defect - doesn't work debug :( – Volodymyr Jan 04 '13 at 08:08
  • I'm using scala 2.10. And I didn't try with 2.9 – Kamil Lelonek Jan 04 '13 at 15:11
  • The code looks OK with nothing causing much in the way of trouble. This is very weird and probably down to some JVM arguments. Having a strong PC and SSD myself, I've seen Scala compilation being as fast as Java. See my answer below for the settings I use. – Nikolaos Jan 06 '13 at 01:53

2 Answers2

5

Add these to eclipse.ini (or edit if present), as are more optimised for Scala development: They should appear below eclipse entries, such as -vm:

-Xverify:none
-Dosgi.requiredJavaVersion=1.6
-Xms900m
-Xmx900m
-Xss2m
-XX:PermSize=256m
-XX:MaxPermSize=256m
-XX:MaxGCPauseMillis=20
-XX:MaxHeapFreeRatio=70
-XX:+ScavengeBeforeFullGC
-XX:+UseParallelOldGC
-XX:+UnlockExperimentalVMOptions
-XX:+UseFastAccessorMethods
-XX:ReservedCodeCacheSize=128m
-XX:+TieredCompilation
-XX:+AggressiveOpts

Probably unlikely, but if you are using CMS GC, remove references to it from the file.

Nikolaos
  • 1,449
  • 2
  • 15
  • 19
  • 1
    Why do you set up `xms` and `xmx` at the same memory? It's not recommended starting with `900m`. Could you also explain why to use `UseParallelOldGC`? – Kamil Lelonek Jan 05 '13 at 22:54
  • Setting up xms and xmx to the same size avoids unnecessary garbage collections as the heap grows over time. When xms is set to something smaller eg 128m and xmx to let's say 900m, as memory pressure is added to the GC, usage grows in increments such as 256, 512, etc. Every time this happens it triggers a collection which may pause your IDE for a bit. As for "parallel old GC", it instructs the JVM to parallelize old generation collections, so it's faster than serial old-gen collections (the default). – Nikolaos Jan 06 '13 at 01:46
  • 2
    What do you mean it's not recommended to start with 900m? I've never heard this before. Where did you hear this? Starting up with all the memory you plan to use is a good strategy, usually. – Nikolaos Jan 06 '13 at 01:48
  • 1
    Oh, it's my fault. Some time ago I read about setting up some parameters in eclipse which can't be at the same level, but it appears that it wasn't about xms and xmx. I tried use your -vmargs and everything look nice when I opened my old project. Unfortunately I'm not writing now any new project so I can't try it on something bigger. When I start next project I'll use scala for it and if it goes well I will mark answer as accepted. – Kamil Lelonek Jan 06 '13 at 09:35
-1

While I have not done this with Android specific development, I hit similar problems while doing the "Function Programming Principles in Scala" Coursera course. What it turned out to be was the the PermGen space for the Eclipse JVM was maxing out which causes all sorts of random and chaotic Eclipse behaviors. It turns out that behind the scenes, the Scala compiler generages many MANY more times the number of class files than for a Java project of roughly the same size. So, I added the following to the command line start-up for Eclipse:

-XX:MaxPermSize=256m

Before this, I was having the weirdest Eclipse errors, at the oddest times with no reasonable way to consistently reproduce them. And I had this for the first three weeks of the course. I almost quit the course since I was using TypeSafe's version of Eclipse I had downloaded explicitly for the course. Once I added the above to the JVM start-up for Eclipse, I didn't have another single issue. I couldn't believe how awesome the Scala IDE was as I had never been able to use it stable prior to doing this.

Hope this helps.

chaotic3quilibrium
  • 5,661
  • 8
  • 53
  • 86
  • Well, I was not able to tell from reading your original post. Did you put it somewhere and I missed it? – chaotic3quilibrium Jan 06 '13 at 02:29
  • No, I didn't mention that. Isn't it standart setting in eclipse now, because I don't remeber putting it in eclipse.ini? – Kamil Lelonek Jan 06 '13 at 08:26
  • It wasn't for mine. However, I start Eclipse from a batch file I created myself. So, you might be correct...although that doesn't explain why the one I dl'ed from Typesafe for the Coursera course didn't have it's set high enough. – chaotic3quilibrium Jan 06 '13 at 18:17