It is currently 12 Sep 2025, 08:36
   
Text Size

Heap space issues

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins

Heap space issues

Postby timmermac » 03 Jul 2011, 05:12

I've downloaded Eclipse and Subclipse and am running Forge from inside of that. Even with changing eclipse.ini to have -Xms1000m -Xmx1000, running GUI_NewGame results in Forge only getting a heap of 266338304 bytes. I did a text search within the project, and I discovered a few instances of -Xmx1024m, however, I'm not sure that that is ever being reached. I'm thinking that perhaps there needs to be -Xms1000m parameters entered into the code at the appropriate places as well.
"I just woke up, haven't had coffee, let alone a pee in 7 days, and I find out you stole my ass and made a ...mini-me! Carter, I should be irked currently, yes?" - Jack O'Neill
User avatar
timmermac
Tester
 
Posts: 1512
Joined: 17 May 2010, 20:36
Has thanked: 18 times
Been thanked: 95 times

Re: Heap space issues

Postby Chris H. » 03 Jul 2011, 12:35

The params in the eclipse.ini probably only effect the Eclipse app itself and most likely have no effect on the java code (ex: Forge) that is run from within Eclipse.

Try this instead. Go to:

Run -> Run Configurations... -> Java Application -> your run configuration

Click on the second tab which should be named (x)= Arguments. Start off by adding the VM argument to the correct box and then click on the Apply button. Run Forge for a few games and see how it behaves.

You can then add in your program arguments to the other box and run the same tests.

Note that the arguments that you want to apply to forge while running forge from within the Eclipse dev system need to be added to this Run Configurations window, and make sure to click on the Apply button. The pic below only displays the VM argument, I forgot to add in the program argument but this should be enough to get you started. Good luck. :D


`
Attachments
run config.jpg
Last edited by Chris H. on 03 Jul 2011, 23:14, edited 1 time in total.
Reason: spelling
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Heap space issues

Postby timmermac » 04 Jul 2011, 00:27

I was running Forge concurrently with VisualVM with the -Xms1000m -Xmx1000m arguments added into the run configuration, and I'm still having some issues. For whatever reason, the heap continued to increase through the various matches until during the 4th consecutive match, the heap got up to over 950 million bytes and Forge locked up in the middle of me trying to play a spell. In looking through the console that Eclipse provides, it's really looking like the Image Cache is causing the heap to grow. I don't know enough about programming to be able to tell for sure what's going on, but my gut feeling is that the Image Cache isn't being cleared. I keep seeing exceptions being thrown in the console. Here's what the console says.
Console Error Message | Open
com.google.common.collect.ComputationException: javax.imageio.IIOException: Bogus DQT index 5
at forge.ImageCache$1.apply(ImageCache.java:103)
at forge.ImageCache$1.apply(ImageCache.java:1)
at com.google.common.collect.MapMaker$StrategyImpl.compute(MapMaker.java:592)
at com.google.common.collect.MapMaker$StrategyImpl.compute(MapMaker.java:462)
at com.google.common.collect.CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2045)
at forge.ImageCache.getImage(ImageCache.java:161)
at forge.ImageCache.getImage(ImageCache.java:132)
at arcane.ui.CardPanel.setCard(CardPanel.java:478)
at forge.GuiDisplay4.setCard(GuiDisplay4.java:531)
at forge.gui.GuiUtils$1.valueChanged(GuiUtils.java:209)
at javax.swing.JList.fireSelectionValueChanged(Unknown Source)
at javax.swing.JList$ListSelectionHandler.valueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
at javax.swing.DefaultListSelectionModel.setSelectionInterval(Unknown Source)
at javax.swing.JList.setSelectedIndex(Unknown Source)
at forge.gui.ListChooser.show(ListChooser.java:244)
at forge.gui.GuiUtils.getChoices(GuiUtils.java:213)
at forge.gui.GuiUtils.getChoiceOptional(GuiUtils.java:147)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.changeHiddenOriginResolveHuman(AbilityFactory_ChangeZone.java:636)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.changeHiddenOriginResolve(AbilityFactory_ChangeZone.java:559)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.changeZoneResolve(AbilityFactory_ChangeZone.java:256)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.access$1(AbilityFactory_ChangeZone.java:251)
at forge.card.abilityFactory.AbilityFactory_ChangeZone$2.resolve(AbilityFactory_ChangeZone.java:76)
at forge.card.abilityFactory.AbilityFactory.resolve(AbilityFactory.java:1643)
at forge.MagicStack.resolveStack(MagicStack.java:782)
at forge.Phase.passPriority(Phase.java:699)
at forge.ComputerAI_General.stackResponse(ComputerAI_General.java:442)
at forge.ComputerAI_General.stack_not_empty(ComputerAI_General.java:387)
at forge.gui.input.InputControl.updateInput(InputControl.java:183)
at forge.GuiInput.update(GuiInput.java:30)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at forge.MyObservable.updateObservers(MyObservable.java:17)
at forge.gui.input.InputControl.resetInput(InputControl.java:89)
at forge.Phase.passPriority(Phase.java:690)
at forge.gui.input.Input_PassPriority.selectButtonOK(Input_PassPriority.java:46)
at forge.GuiInput.selectButtonOK(GuiInput.java:57)
at forge.GuiDisplay4.okButtonActionPerformed(GuiDisplay4.java:1111)
at forge.GuiDisplay4.access$3(GuiDisplay4.java:1110)
at forge.GuiDisplay4$31.actionPerformed(GuiDisplay4.java:864)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: javax.imageio.IIOException: Bogus DQT index 5
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at arcane.ui.util.ImageUtil.getImage(ImageUtil.java:43)
at forge.ImageCache$1.apply(ImageCache.java:96)
... 68 more


Unfortunately, I've got no clue what this means, so I can't tell exactly what's wrong, but I do know what the symptoms of the malfunction are. As a user continues to use Forge, it uses more and more memory until it eventually is using more memory than is allocated for the program to run, and it locks everything up.
"I just woke up, haven't had coffee, let alone a pee in 7 days, and I find out you stole my ass and made a ...mini-me! Carter, I should be irked currently, yes?" - Jack O'Neill
User avatar
timmermac
Tester
 
Posts: 1512
Joined: 17 May 2010, 20:36
Has thanked: 18 times
Been thanked: 95 times

Re: Heap space issues

Postby Chris H. » 04 Jul 2011, 01:12

timmermac wrote:I was running Forge concurrently with VisualVM with the -Xms1000m -Xmx1000m arguments added into the run configuration, and I'm still having some issues. For whatever reason, the heap continued to increase through the various matches until during the 4th consecutive match, the heap got up to over 950 million bytes and Forge locked up in the middle of me trying to play a spell. In looking through the console that Eclipse provides, it's really looking like the Image Cache is causing the heap to grow. I don't know enough about programming to be able to tell for sure what's going on, but my gut feeling is that the Image Cache isn't being cleared. I keep seeing exceptions being thrown in the console. Here's what the console says.
Console Error Message | Open
com.google.common.collect.ComputationException: javax.imageio.IIOException: Bogus DQT index 5
at forge.ImageCache$1.apply(ImageCache.java:103)
at forge.ImageCache$1.apply(ImageCache.java:1)
at com.google.common.collect.MapMaker$StrategyImpl.compute(MapMaker.java:592)
at com.google.common.collect.MapMaker$StrategyImpl.compute(MapMaker.java:462)
at com.google.common.collect.CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2045)
at forge.ImageCache.getImage(ImageCache.java:161)
at forge.ImageCache.getImage(ImageCache.java:132)
at arcane.ui.CardPanel.setCard(CardPanel.java:478)
at forge.GuiDisplay4.setCard(GuiDisplay4.java:531)
at forge.gui.GuiUtils$1.valueChanged(GuiUtils.java:209)
at javax.swing.JList.fireSelectionValueChanged(Unknown Source)
at javax.swing.JList$ListSelectionHandler.valueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.fireValueChanged(Unknown Source)
at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
at javax.swing.DefaultListSelectionModel.changeSelection(Unknown Source)
at javax.swing.DefaultListSelectionModel.setSelectionInterval(Unknown Source)
at javax.swing.JList.setSelectedIndex(Unknown Source)
at forge.gui.ListChooser.show(ListChooser.java:244)
at forge.gui.GuiUtils.getChoices(GuiUtils.java:213)
at forge.gui.GuiUtils.getChoiceOptional(GuiUtils.java:147)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.changeHiddenOriginResolveHuman(AbilityFactory_ChangeZone.java:636)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.changeHiddenOriginResolve(AbilityFactory_ChangeZone.java:559)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.changeZoneResolve(AbilityFactory_ChangeZone.java:256)
at forge.card.abilityFactory.AbilityFactory_ChangeZone.access$1(AbilityFactory_ChangeZone.java:251)
at forge.card.abilityFactory.AbilityFactory_ChangeZone$2.resolve(AbilityFactory_ChangeZone.java:76)
at forge.card.abilityFactory.AbilityFactory.resolve(AbilityFactory.java:1643)
at forge.MagicStack.resolveStack(MagicStack.java:782)
at forge.Phase.passPriority(Phase.java:699)
at forge.ComputerAI_General.stackResponse(ComputerAI_General.java:442)
at forge.ComputerAI_General.stack_not_empty(ComputerAI_General.java:387)
at forge.gui.input.InputControl.updateInput(InputControl.java:183)
at forge.GuiInput.update(GuiInput.java:30)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at forge.MyObservable.updateObservers(MyObservable.java:17)
at forge.gui.input.InputControl.resetInput(InputControl.java:89)
at forge.Phase.passPriority(Phase.java:690)
at forge.gui.input.Input_PassPriority.selectButtonOK(Input_PassPriority.java:46)
at forge.GuiInput.selectButtonOK(GuiInput.java:57)
at forge.GuiDisplay4.okButtonActionPerformed(GuiDisplay4.java:1111)
at forge.GuiDisplay4.access$3(GuiDisplay4.java:1110)
at forge.GuiDisplay4$31.actionPerformed(GuiDisplay4.java:864)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: javax.imageio.IIOException: Bogus DQT index 5
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at arcane.ui.util.ImageUtil.getImage(ImageUtil.java:43)
at forge.ImageCache$1.apply(ImageCache.java:96)
... 68 more


Unfortunately, I've got no clue what this means, so I can't tell exactly what's wrong, but I do know what the symptoms of the malfunction are. As a user continues to use Forge, it uses more and more memory until it eventually is using more memory than is allocated for the program to run, and it locks everything up.
`
Hmmm, there is an issue 134 on googlecode cardforge about a "Bogus DQT index 5" error exception. Sol seems to think that it might be caused when clicking on a corrupt card image.

Rob re-uploaded the set pics in response to notice that some of these card pics were corrupt. It may not help but you might want to consider removing the folders containing the set pics and then re-download them one more time. A time consuming experiment but if this helps to alleviate this issue then it would be worth the time invested.

Once again, good luck.
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Heap space issues

Postby timmermac » 04 Jul 2011, 01:52

I'll have to try that. I don't know that it will have an effect on my heap issues, but it won't hurt to try. I've got a screenshot illustrating just what's happening to my heap space. It'll be attached. I'm only ever able to play 2 or 3 matches in a row, no matter what my heap space min/max are set to. I don't remember having this much trouble with Forge until January or February, so some time in there is when how Forge uses memory changed.
Attachments
VirtualVM Forge Screenshot.PNG
This is what Forge did during a 3 match set.
"I just woke up, haven't had coffee, let alone a pee in 7 days, and I find out you stole my ass and made a ...mini-me! Carter, I should be irked currently, yes?" - Jack O'Neill
User avatar
timmermac
Tester
 
Posts: 1512
Joined: 17 May 2010, 20:36
Has thanked: 18 times
Been thanked: 95 times

Re: Heap space issues

Postby Braids » 09 Jul 2011, 05:55

i have steadily been committing code changes to reduce the number of temporary CardList instances we use in several places. this should lower unnecessary heap allocations. it has made forge somewhat faster; it is most noticable in the deck editors when filtering by name using the Filter menu (not the text box).

i'll check my messages in about 9.5 hours to see if i broke anything serious. i was much more careful changing CardFactory this time and more thorough with my own acceptance tests.

longer term heap issues won't go away until we switch more hash fields to trees and find memory leaks like the ones timmermac experiences.
"That is the dumbest thing I've ever seen." --Rob Cashwalker, regarding Innistrad double-sided cards. One of the first times he and I have ever agreed on something. ;)
User avatar
Braids
Programmer
 
Posts: 556
Joined: 22 Jun 2011, 00:39
Location: Unknown. Hobby: Driving myself and others to constructive madness.
Has thanked: 1 time
Been thanked: 1 time

Re: Heap space issues

Postby jendave » 14 Jul 2011, 06:12

Snapshot of memory usage before the New Game screen even comes up.
Attachments
heap.png
jendave
 
Posts: 307
Joined: 01 Jun 2008, 07:19
Has thanked: 8 times
Been thanked: 21 times

Re: Heap space issues

Postby Braids » 15 Jul 2011, 02:33

jendave wrote:Snapshot of memory usage before the New Game screen even comes up.
ok, yes, pretty data. Object arrays? unexpected.

what message are you conveying? are you trying to make a case for mocks, leaner startup . . . ? (profit?)
"That is the dumbest thing I've ever seen." --Rob Cashwalker, regarding Innistrad double-sided cards. One of the first times he and I have ever agreed on something. ;)
User avatar
Braids
Programmer
 
Posts: 556
Joined: 22 Jun 2011, 00:39
Location: Unknown. Hobby: Driving myself and others to constructive madness.
Has thanked: 1 time
Been thanked: 1 time

Re: Heap space issues

Postby Chris H. » 15 Jul 2011, 13:41

Hmmm, does this mean that we should at some point get back to the lazy card factory at some point?
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Heap space issues

Postby jendave » 15 Jul 2011, 14:56

Braids wrote:
jendave wrote:Snapshot of memory usage before the New Game screen even comes up.
ok, yes, pretty data. Object arrays? unexpected.

what message are you conveying? are you trying to make a case for mocks, leaner startup . . . ? (profit?)
No, not mocks or anything. The code uses arrays WAY too much. Tons of code use .toArray(). I started removing all of the Object[] and Deck[] instances, but it is a lot of work so far. Also, it is very invasive. I'll look at it more this weekend.
jendave
 
Posts: 307
Joined: 01 Jun 2008, 07:19
Has thanked: 8 times
Been thanked: 21 times

Re: Heap space issues

Postby Chris H. » 15 Jul 2011, 15:09

Just did a search in Eclipse and it found 247 matches for ".toArray".
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Heap space issues

Postby Braids » 15 Jul 2011, 17:03

jendave wrote: . . . The code uses arrays WAY too much. Tons of code use .toArray(). I started removing all of the Object[] and Deck[] instances, but it is a lot of work so far. Also, it is very invasive. I'll look at it more this weekend.
please keep in mind that we have some good support for Generators, including Generators that filter or apply transforms to other Generators. this happens lazily, at iteration. i've also found that most Generators can Death Ward Regenerate, meaning you can call the generate method on them (or YieldUtils.toIterable) more than once without problems. Iterable and Iterator are nice, too.

edit 1. be careful with YieldUtils.toIterable; i think it might leak memory if you don't finish iterating over all the elements.

edit 2. whom do i have to svn blame praise for my new "Programmer" title?
"That is the dumbest thing I've ever seen." --Rob Cashwalker, regarding Innistrad double-sided cards. One of the first times he and I have ever agreed on something. ;)
User avatar
Braids
Programmer
 
Posts: 556
Joined: 22 Jun 2011, 00:39
Location: Unknown. Hobby: Driving myself and others to constructive madness.
Has thanked: 1 time
Been thanked: 1 time

Re: Heap space issues

Postby Chris H. » 15 Jul 2011, 17:23

Braids wrote:edit 2. whom do i have to svn blame praise for my new "Programmer" title?
`
I would assume that this would require a site Administrator or CCGHQ Administrator and/or possibly a Global moderator.

As a Forge Forum moderator I do not believe that I have that power. :mrgreen:
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Heap space issues

Postby friarsol » 15 Jul 2011, 17:43

Chris H. wrote:
Braids wrote:edit 2. whom do i have to svn blame praise for my new "Programmer" title?
`
I would assume that this would require a site Administrator or CCGHQ Administrator and/or possibly a Global moderator.

As a Forge Forum moderator I do not believe that I have that power. :mrgreen:
I think it's based on number of posts.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 21 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 21 users online :: 0 registered, 0 hidden and 21 guests (based on users active over the past 10 minutes)
Most users ever online was 7967 on 09 Sep 2025, 23:08

Users browsing this forum: No registered users and 21 guests

Login Form