Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > ASP .Net > ASP General > Storing objects in Session Variables - exactly why not?

Reply
Thread Tools

Storing objects in Session Variables - exactly why not?

 
 
mjkahn
Guest
Posts: n/a
 
      03-25-2005
I've read (and read!) that you shouldn't store objects in Session variables.
I've read these reasons:

- The object takes up memory that may not be freed until the session times
out. Better to create the object only when you actually use it.

- Causes poor performance because the thread that created the object has to
service all requests for it.

Assuming I can live with the memory and performance implications (a big if,
but let's assume it for a minute), what other reasons are there?

MJ.

 
Reply With Quote
 
 
 
 
Jason Brown [MSFT]
Guest
Posts: n/a
 
      03-26-2005
The reasons against this diminish as server power grows - obviously if you
have a really hefty server, you can handle the memory usage issues. THe
threading issue is fairly easily overcome by making sure you only use free
threaded objects (such as MSXML.FreeThreadedDomDocument).

It can get to be a bit of a chore to manage them too, and debugging can be
tricky, but if you think you can handle that, along with the memory
requirements, then feel free. Just make sure you have an idea of how much
memory you're going to end up using.


--
Jason Brown
Microsoft GTSC, IIS

This posting is provided "AS IS" with no warranties, and confers no rights.



"mjkahn" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> I've read (and read!) that you shouldn't store objects in Session
> variables.
> I've read these reasons:
>
> - The object takes up memory that may not be freed until the session times
> out. Better to create the object only when you actually use it.
>
> - Causes poor performance because the thread that created the object has
> to
> service all requests for it.
>
> Assuming I can live with the memory and performance implications (a big
> if,
> but let's assume it for a minute), what other reasons are there?
>
> MJ.
>



 
Reply With Quote
 
 
 
 
Thomas
Guest
Posts: n/a
 
      03-26-2005
i'm using ADO objects in Session and Application memory for over 3 years now
without any problems at all. having a shared pool of ADO.Connection objects
that is assigned to new clients through global.asa proofed to be much faster
than allocate and instantiate the objects at runtime.

threading issue i haven't noticed, although we have quite a few conqurrent
users on all the time, server cpu load is <6% avr (3ghz system).

of course memory usage is very high, the web's application pool uses around
1 - 1.5gb. but hey, memory is cheap nowadays

- thomas


"mjkahn" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> I've read (and read!) that you shouldn't store objects in Session
> variables.
> I've read these reasons:
>
> - The object takes up memory that may not be freed until the session times
> out. Better to create the object only when you actually use it.
>
> - Causes poor performance because the thread that created the object has
> to
> service all requests for it.
>
> Assuming I can live with the memory and performance implications (a big
> if,
> but let's assume it for a minute), what other reasons are there?
>
> MJ.
>



 
Reply With Quote
 
Bob Barrows [MVP]
Guest
Posts: n/a
 
      03-26-2005
Thomas wrote:
> i'm using ADO objects in Session and Application memory for over 3
> years now without any problems at all. having a shared pool of
> ADO.Connection objects that is assigned to new clients through
> global.asa proofed to be much faster than allocate and instantiate
> the objects at runtime.


And exactly how did you determine this?

>
> threading issue i haven't noticed, although we have quite a few
> conqurrent users on all the time, server cpu load is <6% avr (3ghz
> system).
> of course memory usage is very high, the web's application pool uses
> around 1 - 1.5gb. but hey, memory is cheap nowadays
>


By doing this, you've prevented the use of OLE DB session pooling, and, if
you haven't changed the threading model of ADO from apartment to
free-threaded (which you should not do if using Jet), you've serialized all
of your database access.

Just because you cannot perceive a performance issue does not mean one does
not exist.

Bob Barrows
--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"


 
Reply With Quote
 
Thomas
Guest
Posts: n/a
 
      03-26-2005
> And exactly how did you determine this?

http://www.microsoft.com/downloads/d...displaylang=en


> Just because you cannot perceive a performance issue does not mean one
> does not exist.


just because you assume i didn't knew about the serialized execution problem
does not mean i didn't knew

see, the connections are assigned from a pool of connections. of course
you're right: if 2 users receive the same object, their fired sql code will
be serialized. easy workaround: every user receives a different connection
object. add some logic (i.e. if a user opens 2 browsers and creates thus 2
sessions, assign him only 1 connection) and you're set. counter variables
measure if a shared connection object is still in use, if not it is
destroyed after session end.
of course, it needs some programming and session startup is slower than
without. but the gained speed afterwards make this worth.

this works pretty neat and faster than any other solution i came across so
far. it works fine even with ~900 concurrent user sessions (with 20min
timeout). i'm open to even better suggestions, tho...

- thomas


"Bob Barrows [MVP]" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> Thomas wrote:
>> i'm using ADO objects in Session and Application memory for over 3
>> years now without any problems at all. having a shared pool of
>> ADO.Connection objects that is assigned to new clients through
>> global.asa proofed to be much faster than allocate and instantiate
>> the objects at runtime.

>
> And exactly how did you determine this?
>
>>
>> threading issue i haven't noticed, although we have quite a few
>> conqurrent users on all the time, server cpu load is <6% avr (3ghz
>> system).
>> of course memory usage is very high, the web's application pool uses
>> around 1 - 1.5gb. but hey, memory is cheap nowadays
>>

>
> By doing this, you've prevented the use of OLE DB session pooling, and, if
> you haven't changed the threading model of ADO from apartment to
> free-threaded (which you should not do if using Jet), you've serialized
> all of your database access.
>
> Just because you cannot perceive a performance issue does not mean one
> does not exist.
>
> Bob Barrows
> --
> Microsoft MVP - ASP/ASP.NET
> Please reply to the newsgroup. This email account is my spam trap so I
> don't check it very often. If you must reply off-line, then remove the
> "NO SPAM"
>



 
Reply With Quote
 
Bob Barrows [MVP]
Guest
Posts: n/a
 
      03-26-2005
Thomas wrote:
>> And exactly how did you determine this?

>
> http://www.microsoft.com/downloads/d...displaylang=en
>
>


Microsoft has published results of stress tests indicating the opposite of
what you say your results are. I suspect you were not actually taking
adbantage of session pooling when you ran your tests, but of course, this is
only a suspicion.

> far. it works fine even with ~900 concurrent user sessions (with 20min
> timeout). i'm open to even better suggestions, tho...
>


The best suggestion I have is the one that comes from Microsoft: take
advantage of session pooling by instantiating and opening connections on
each page, closing them as soon as you are finished using them. Only the
first opening of a connection will take time. Once the connection is in the
pool, subsequent uses will not require the same time to open them.

By taking advantage of session pooling, you minimize the number of
connections to your database. Don't forget: each connection uses memory on
the database server as well as the web server (assuming you are using a
server-based dbms, which you must be with 900 concurrent users).

Here's more information:
http://msdn.microsoft.com/library/en...l/pooling2.asp
http://support.microsoft.com/?scid=kb;en-us;Q176056
http://support.microsoft.com/default...b;en-us;191572
http://support.microsoft.com/default...b;en-us;324686

connection failures caused by pooling disablement
http://support.microsoft.com/default...b;en-us;328476

implicit connections:
http://support.microsoft.com/?kbid=271128

Bob Barrows

--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"


 
Reply With Quote
 
Thomas
Guest
Posts: n/a
 
      03-27-2005
> Microsoft has published results of stress tests indicating the opposite of
> what you say your results are. I suspect you were not actually taking
> adbantage of session pooling when you ran your tests, but of course, this
> is only a suspicion.


hmm thats interesting.

wouldn't be OLE DB connections pooled when using default settings? i ran the
tests ~3 years ago on IIS5 with connection code similar to the one below -
but of course with many different pages with different (more expensive)
queries and multiple requests.

-----------------------------------------
connection opens on each page:

FILE: TEST_NOSESSION.ASP:
<% Option Explicit

Const adOpenForwardOnly = 0

Dim oConn, rsRecords, sOutput
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.open
"provider=SQLOLEDB;server=localhost;uid=webuser;pw d=test123;database=movies;QuotedID=No"

Set rsRecords = Server.CreateObject("ADODB.Recordset")
rsRecords.Open "SELECT movies.mov_name FROM movies WHERE mov_id > 100",
oConn, adOpenForwardOnly

Do Until rsRecords.EOF
sOutput = sOutput & "<br>" & rsRecords("mov_name")
rsRecords.MoveNext
Loop
rsRecords.close
response.write sOutput

oConn.close

set rsRecords = nothing
set oConn = nothing

%>

---------------------------------------------
connection opened in global.asa:

FILE GLOBAL.ASA: (simplified)
<%
Sub Session_OnStart()
Call ConnectDB()
End Sub

Sub Session_OnEnd()
' some stuff here as well
End Sub

Function ConnectDB()
If (check here if for this user a Connection object already exists)
= false then
' new connection
Set Application("DB_xxx") =
Server.CreateObject("ADODB.Connection")
Application("DB_xxx").open
"provider=SQLOLEDB;server=localhost;uid=webuser;pw d=test123;database=movies;QuotedID=No"
End If

Set Session("DB") = Application("DB_xxx")
End Function
%>

FILE: TEST_WITHSESSION.ASP:
<% Option Explicit

Const adOpenForwardOnly = 0

Dim rsRecords, sOutput

Set rsRecords = Server.CreateObject("ADODB.Recordset")
rsRecords.Open "SELECT movies.mov_name FROM movies WHERE mov_id > 100",
Session("DB"), adOpenForwardOnly

Do Until rsRecords.EOF
sOutput = sOutput & "<br>" & rsRecords("mov_name")
rsRecords.MoveNext
Loop
rsRecords.close
response.write sOutput

set rsRecords = nothing
%>


> The best suggestion I have is the one that comes from Microsoft: take
> advantage of session pooling by instantiating and opening connections on
> each page, closing them as soon as you are finished using them. Only the
> first opening of a connection will take time. Once the connection is in
> the pool, subsequent uses will not require the same time to open them.


what about the Server.CreateObject? i always thought object creation and
instantiation would add heavy overhead... and thus negatively affect
performance

>
> By taking advantage of session pooling, you minimize the number of
> connections to your database. Don't forget: each connection uses memory on
> the database server as well as the web server (assuming you are using a
> server-based dbms, which you must be with 900 concurrent users).


thats true. the db shows quite a lot of connections. but because of the 900
concurrent users are not all firing queries at the same time, the db is not
overloaded. of course the memory requirements are quite huge, db + web uses
around 2.5gb of memmory

> Here's more information:
> http://msdn.microsoft.com/library/en...l/pooling2.asp
> http://support.microsoft.com/?scid=kb;en-us;Q176056
> http://support.microsoft.com/default...b;en-us;191572
> http://support.microsoft.com/default...b;en-us;324686


interesting lecture for a boring sunday... erhm wait, its easter!

thanks for your input and happy easter from switzerland!

- thomas


 
Reply With Quote
 
Bob Barrows [MVP]
Guest
Posts: n/a
 
      03-27-2005
Thomas wrote:
>> Microsoft has published results of stress tests indicating the
>> opposite of what you say your results are. I suspect you were not
>> actually taking
>> adbantage of session pooling when you ran your tests, but of course,
>> this is only a suspicion.

>
> hmm thats interesting.
> wouldn't be OLE DB connections pooled when using default settings?


Yes, in IIS, session pooling is on by default (which can be confirmed by
reading the material in the links I provided). However, there are coding
practices that will cause it to be disabled. A quick perusal of your code
does not reveal any of the practices i was thinking of.

<snip>

Thanks for the code. I will try it myself sometime.
Can you share the results of your tests? How much of a difference was
achieved by using the Session-bound object?

PS. Have you at least changed the threading model of your ADO objects by
using the makfre15.bat batch file which can be found in your ADO folder? If
you are not using Jet, you really should do this. Most of my objections to
caching the object in session go away if you change the treading model.
>
>
> what about the Server.CreateObject? i always thought object creation
> and instantiation would add heavy overhead... and thus negatively affect
> performance
>


In earlier versions of IIS, it was always recommended that you get MTS
involved by using Server.CreateObject. In later versions (5.1 and higher, I
think) the reasons for encouraging the use of server.createobject have been
resolved. Performance can be improved by using the vbscript version of
CreateObject (simply leave out the "Server.")

Would it be too much to ask for you to repeat your tests using CreateObject
instead of Server.CreateObject?

>>
>> By taking advantage of session pooling, you minimize the number of
>> connections to your database. Don't forget: each connection uses
>> memory on the database server as well as the web server (assuming you are
>> using a server-based dbms, which you must be with 900 concurrent users).

>
> thats true. the db shows quite a lot of connections. but because of
> the 900 concurrent users are not all firing queries at the same time, the
> db
> is not overloaded. of course the memory requirements are quite huge, db +
> web uses around 2.5gb of memmory
>

Not only that, but you also may be violating your license agreement for your
database server. But I am not a lawyer. Just providing some food for
thought.

Have a good Easter,
Bob Barrows
--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"


 
Reply With Quote
 
Thomas
Guest
Posts: n/a
 
      03-27-2005
> Thanks for the code. I will try it myself sometime.
> Can you share the results of your tests? How much of a difference was
> achieved by using the Session-bound object?


it was roughly in the regions of 20% performance gain. i will defenitely
redo my tests in the near future. the configuration has changed (iis6,
windows2003, new server, new ado). also from what i read here and in your
links, my solution might not be faster anymore in the current environement.
if i can get rid of manual pooling without performance-loss, i'll do this
happily - especially as this would free up ressources.

> PS. Have you at least changed the threading model of your ADO objects by
> using the makfre15.bat batch file which can be found in your ADO folder?
> If you are not using Jet, you really should do this. Most of my objections
> to caching the object in session go away if you change the treading model.
>>


nope. i don't even have this batch file... maybe because in windows2003 mdac
2.8 is already included?

> Would it be too much to ask for you to repeat your tests using
> CreateObject instead of Server.CreateObject?


not at all. i'll prepare some new tests. i always thought it
Server.CreateObject was recommended over CreateObject

> Not only that, but you also may be violating your license agreement for
> your database server. But I am not a lawyer. Just providing some food for
> thought.


honestly, i never clearly understood the licencing of the db server. the
seller sold us a 5-client license of ms-sql server standard. still, does a
5-client-license mean
- 5 different machines connecting to the db-server? - there's only 1 machine
in my setup
- 5 different db-login connecting at the same time to the db-server? - all
my users use the same login
- 5 different connections? - hopefully not. even when you open up the
administration manager, you get more than these numbers of connections...


cheers,
thomas


 
Reply With Quote
 
Bob Barrows [MVP]
Guest
Posts: n/a
 
      03-27-2005
Thomas wrote:
>> Thanks for the code. I will try it myself sometime.
>> Can you share the results of your tests? How much of a difference was
>> achieved by using the Session-bound object?

>
> it was roughly in the regions of 20% performance gain. i will
> defenitely redo my tests in the near future. the configuration has
> changed (iis6, windows2003, new server, new ado). also from what i
> read here and in your links, my solution might not be faster anymore
> in the current environement. if i can get rid of manual pooling
> without performance-loss, i'll do this happily - especially as this
> would free up ressources.
>> PS. Have you at least changed the threading model of your ADO
>> objects by using the makfre15.bat batch file which can be found in
>> your ADO folder? If you are not using Jet, you really should do
>> this. Most of my objections to caching the object in session go away
>> if you change the treading model.
>>>

>
> nope. i don't even have this batch file... maybe because in
> windows2003 mdac 2.8 is already included?


Interesting. I do not see it on one of our W2003 servers either. Several
possibilities come to mind:

1. It's no longer necessary to do this change in W2003
2. They don't want you doing this change in W2003
3. You can't make this change in W2003

I'm not sure which is the correct reason.

All the batch file does is run the registry merge file called ADOFRE15.REG
(contained in the same folder) that contains these registry keys:

REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0000050 7-0000-0010-8000-00AA006D2EA4}\InprocServer32]
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0000051 4-0000-0010-8000-00AA006D2EA4}\InprocServer32]
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0000050 B-0000-0010-8000-00AA006D2EA4}\InprocServer32]
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0000053 5-0000-0010-8000-00AA006D2EA4}\InprocServer32]
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0000054 1-0000-0010-8000-00AA006D2EA4}\InprocServer32]
"ThreadingModel"="Both"

I don't have access to the registries on our W2003 servers right now so I
can't investigate more thoroughly.


>
>> Would it be too much to ask for you to repeat your tests using
>> CreateObject instead of Server.CreateObject?

>
> not at all. i'll prepare some new tests. i always thought it
> Server.CreateObject was recommended over CreateObject


As did I. I recently had it pointed out to me that things had changed.

Bob Barrows
--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Storing objects in Session variables Harlan Messinger ASP .Net 5 04-02-2010 05:16 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Best practice : storing objects in session-variables ? david@nospam.com ASP .Net 9 09-11-2006 09:38 AM
Unable to serialize the session state. Please note that non-serializable objects or MarshalByRef objects are not permitted when session state mode is 'StateServer' or 'SQLServer'. Mike Larkin ASP .Net 1 05-23-2005 12:33 PM
Storing COM objects in a session variable Sandra ASP .Net 0 10-21-2003 04:08 AM



Advertisments