4

I am trying to instantiate a huge ArrayList

List<Integer> list = new ArrayList<Integer>(Integer.MAX_VALUE);  

Running it in eclipse I get:

java.lang.OutOfMemoryError: Requested array size exceeds VM limit  

If I do:

List<Integer> list = new ArrayList<Integer>(Integer.MAX_VALUE - 2);  

I get a different error:

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory failed; error='The paging file is too small for this operation to complete'   

#
# there is insifficent memory for the Java Runtime Environment to continue.   

I start the program with the following setting in the run configurations in eclipse:
-Xmx8G

So what is the problem here? Even if I increase to -Xmx16G it still gives the same error

Update
I am bit confused, does the actual size of RAM matter here? Dont processes have access to unlimited virtual memory thanks to paging?

Jim
  • 3,845
  • 3
  • 22
  • 47
  • Do you have 16 GB of RAM on your computer? – Abra May 15 '20 at 15:19
  • @Abra: No, just 6GB. But does it matter? Don't OS do virtual memory swap? – Jim May 15 '20 at 15:31
  • @Abra: `Can the operating system assign all its RAM to your java process` how can I check that? I don't know – Jim May 15 '20 at 15:43
  • @Abra:I get `Invalid initial heap size: -Xms=4G` – Jim May 15 '20 at 15:45
  • Each integer is 4 bytes ( depends on implementation though ) Then 2^31.2^2 = 2^33 bytes is around 8.6 GB. Even if your RAM is 16GB my guess is that OS in terms of allocating memory for one single process or Eclipse IDE will have some restriction on maximum value of the heap setting. Also JVM needs some space for its GC to breath. – SomeDude May 15 '20 at 16:00
  • @SomeDude: Is that max value configurable somehow? I thought that programs have "unlimited" memory due to Virtual Address Space – Jim May 15 '20 at 16:03
  • 1
    You don't really *need* such a huge array, right? – MC Emperor May 15 '20 at 17:13
  • @MCEmperor: Actually I do but in the context of trying to do a programming exercise. – Jim May 15 '20 at 17:47
  • Swapping does only swap whole processes. You may think of paging. – dan1st May 15 '20 at 19:18
  • @dan1st: May be I messing the terminology with swap space – Jim May 15 '20 at 19:40
  • Maybe. Swapping means swapping whole inactive processes and paging means storing/loading parts of processes memories(pages) – dan1st May 15 '20 at 19:42

1 Answers1

3

I am bit confused, does the actual size of RAM matter here?

Yes, it does.

Don't processes have access to unlimited virtual memory thanks to paging?

Yes they do ... modulo that you need disk space to hold the virtual memory pages. Indeed, that is why you are getting this error:

The paging file is too small for this operation to complete.

This "fix" would be to make the paging file bigger. That has to be done at the OS level.

However, paging means that the operating system has to copy pages from disk to memory when they are needed. And to make room for them it has to copy other (dirty) pages from RAM to disk. All of this copying uses CPU and disk I/O bandwidth and slows down your program.

A typical (C / C++) program can often cope with this to a degree, depending on the application's memory access patterns. But in Java you have the problem that occasionally the GC runs. For a period of time, the GC will be accessing objects in a large number of pages in (essentially) random order. It is worse for a "full" garbage collection.

If the size of the set pages being accessed by an application (i.e. the "working set") is larger than the number of available RAM pages, you can end up "thrashing"; i.e. saturating the I/O system with reads and writes of pages. That is really bad for performance. In extreme cases it can make the OS unresponsive.

Hence, running a Java application with a heap that is larger than the available physical RAM is a potentially dangerous thing to do.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thank you for the clarification. So basically although according to textbooks our programs can consider access to an unlimited virtual address space, in reality even a small percentage need of more RAM than what the system has can lead not only to bad performance but unexpected consequences? Is there some limit over the actual RAM that is relatively safe to consider? – Jim May 16 '20 at 11:19
  • *"So basically although according to textbook ..."*. Which textbook are you talking about? I distinctly remember that my undergraduate textbook on OS principles **warned** about the problem of thrashing. (That was over 30 years ago ...) – Stephen C May 16 '20 at 11:36
  • No. There is no such limit. It depends on the *behavior* of the application; i.e. its pattern of memory accesses. (And indeed ... on what other programs are doing!) And also on the operating system and hardware's ability to transfer pages at the required rate. – Stephen C May 16 '20 at 11:39
  • Yes they do warn about trashing and I understand that the performance would be overly problematic. But it wasn't clear (to me) that a) there must be an OS configuration adjustment for programs to be able to attempt to go over the physical RAM. – Jim May 16 '20 at 11:51
  • So what is a good practice for a program that would require a lot of memory for computations? Ship different versions based on different devices? Focus on subset of devices? – Jim May 16 '20 at 11:51
  • Good practice would be to not run such programs on platforms that don't have enough memory. So ... put the program limitations into the documentation. – Stephen C May 16 '20 at 11:54
  • Seriously, I know of real-world computational tasks that require in excess of 1 TB of RAM. If you have a problem like that you have two choices: 1) get a big enough machine, 2) don't solve the problem. – Stephen C May 16 '20 at 11:56
  • Another possibility is to use the hard disk(or ssd) directly... – dan1st May 16 '20 at 16:39
  • @dan1st: Could you elaborate on that please? – Jim May 16 '20 at 17:49
  • You could try to save the data on the hard disk and then read it using `RandomAccessFile` (if you need to jump between places) or read it sequentially. – dan1st May 16 '20 at 18:01
  • But this depends on what you want to do. – dan1st May 16 '20 at 18:01
  • Or a database. Or a few other alternatives. However accesses and updates will be 3 or more orders of magnitude slower than accessing / updating a field of a Java object in memory. – Stephen C May 17 '20 at 03:29
  • This is way off the topic of this Question (and Answer), not to mention *too broad* for a new Question – Stephen C May 17 '20 at 03:32